contract 2026-08-19
Data

Fields by source

What each of the seven auction sources actually publishes — the condition-data coverage matrix, the source-specific traps, and how to write code that survives the differences.

Seven auction sources feed one API, and they do not publish the same things. A German wholesale platform ships a full inspection report and a DAT equipment catalogue; a Japanese export lot ships an auction inspection sheet and a condition grade; a Korean listing ships neither but carries a deep specification block. This page is the honest map of who gives you what, so you can decide what your product can promise before you build it.

Three layers of data

Every vehicle in the API is described at three levels of normalization. Knowing which layer a field lives on tells you immediately how portable it is.

LayerWhereConsistencyUse it for
The common coreSearch result cards and the top level of both detail endpointsIdentical across all seven sourcesListings, filters, sorting, price display, countdowns — anything that has to work uniformly.
The normalized detail blockvehicle_details on /api/auction/{site}/{id} and /api/car-detailsSame key names everywhere; presence varies by sourceCondition, damages, documents, service history, equipment. Check for the key, do not assume it.
The raw source mapcar_identificationSource-specific. Key names change with each upstreamThe last mile — a value the source publishes that has no cross-source equivalent yet.

The common core is guaranteed in the sense that the field is always in the contract; an individual value can still be null when a particular source does not publish it. fuel_group, for example, is empty for most Japanese lots — and a lot with no recorded fuel matches every fuel filter rather than none, so filtering by fuel never makes those lots unreachable.

What each source gives you

Read this table before you scope a feature. "Sparse" is not a bug to report — it is what the auction house publishes.

SourceWhat it isDepthWhat only it gives you
auto1Europe's largest digital B2B wholesale marketplaceDeep — full vehicle_detailsThe richest equipment data in the API (DAT catalogue), paint-thickness measurements, wheel condition, structured damages with a summary and prior-damage history.
openlanePan-European ex-lease and fleet auctionsDeep — full vehicle_detailsPer-damage free-text comments, typed report PDFs (internal damage, external damage, maintenance, battery health) and its own report index in car_reports.
ecarstradeBelgian online auction house — ex-lease, ex-rental, dealer tradeDeep — full vehicle_detailsThe only source with per-visit service history rows. Also the only source publishing estimated_value_eur, and the only one running blind auctions.
schadeautosNetherlands and Benelux salvage and repairable stockModerateSalvage-focused fields: engine capacity, transmission, VAT/margin status, net and gross export pricing, narrative damage text.
copartCopart Germany salvage and run-and-drive lotsModerateRun-and-drive signal, build-sheet series and special equipment, live lot bid dynamics.
encarSouth Korea's dominant vehicle marketplaceModerate — deep specs, shallow conditionA large specification and options block, photo counts grouped by type, and registration data. Condition and accident detail is thinner than the EU sources.
japanauctionJapanese export inventory pooled from USS, ARAI, AUCNET, BAYAUC and CAAShallow — expect vehicle_details sparse or absentThe auction inspection sheet images, the originating auction house, the lot number, a condition grade, and a published steering side.

Condition data: the coverage matrix

This is the table people actually need. It says which keys of vehicle_details you can expect from which source. Blank means the auction house does not publish it — the field is simply omitted, which is the normal case and not an error.

auto1openlaneecarstradeOther four
damages (per panel)Structured, with summary, count and prior damagesStructured, with a comment per damageFree text + flags only — no per-panel list exists upstreamSparse or absent
inspection_reportsOne URLTyped PDFs by type_idAppraisal PDF + third-party link
documentsService book + service-detail imagesNonepaperwork booleans onlyService-history PDF + appraisal links
service_historySummary onlySummary onlyPer-visit rows — the only source with them
equipmentDAT catalogue (richest)Option list + accessoriesOption listVaries
paperworkPartialCOCAvailable, RegistrationDocsAvailable, IsV5Present, LicensePlatePartial
estimated_repair_costsYesYesYes

Source-specific notes worth knowing

eCarsTrade — blind auctions and the estimate

Most eCarsTrade auctions are blind: every bid is private, so no price is published anywhere and none is inferred. On such a lot current_price, start_price and buy_now_price are all null — and that is the correct, final answer, not a missing value to retry for.

What a blind lot often does carry is estimated_value_eur, the auction house's own valuation (its "eCT Estimation Price"). It is frequently the only number on the lot, which makes it tempting to render in a price slot. Do not. No bid is settled against it and no car is sold at it — a client that shows it as a price quotes customers a figure the auction will not honour. Label it explicitly as an estimate, and never sort or filter on it: it is null for every other source and for roughly 86% of eCarsTrade lots, so any ordering that uses it silently drops them.

json
{
  "auction_id": 7479712,
  "site_name": "ecarstrade",
  "current_price": null,
  "start_price": null,
  "buy_now_price": null,
  "estimated_value_eur": 12000.0
}
A blind lot. Every price field is null and that is final — the estimate is not a substitute.

Japanese auctions — the price is an opening bid

A live Japanese lot has no hammer price until it closes, so current_price on japanauction is the opening bid, not a cost. Roughly a quarter of lots publish no opener at all, and a minority of the rest are nominal starters set far below what the car will fetch. Read it as a floor. buy_now_price is never set on this source, and best-value ranking will flag some of these lots optimistically as a result.

Two more differences: every lot carries the JP origin country, so country=europe excludes them by design — pass country=JP or site=japanauction to target them — and /api/car-details?site=japanauction takes the offer id/UUID rather than the numeric auction id, the same as auto1.

OpenLane — report types

OpenLane classifies each report it publishes. type is the readable name and type_id the source's raw code.

type_idtypeAppears in
1internal_damage_reportinspection_reports
2external_damage_reportinspection_reports
3maintenance_recordsinspection_reports
4option_reportoption_reports
5battery_health_reportinspection_reports
otherreportinspection_reports

Auto1's single inspection report is normalized into the same list with type inspection_report and no type_id. eCarsTrade's appraisal links arrive under documents rather than here, because the source itself presents them as documents.

Naming collisions to be aware of

The same word means different things upstream, which is precisely why the normalized block exists. A downloadable file is Documents[] on Auto1 but ECarsTradeDocuments[] on eCarsTrade — while Documents on OpenLane is a dictionary of paperwork booleans and not a file list at all. If you read car_identification directly, you own that problem. If you read vehicle_details.documents, you do not.

Steering side

steering is left or right on every result card and both detail endpoints, and it is never null for a vehicle in our inventory. japanauction is the only source that publishes a steering field of its own; for every other source the side is read off the car's registration market — a car registered where traffic drives on the left (GB, IE, JP, CY, MT, AU, NZ, ZA, IN, TH, HK, SG) is right, everything else left.

Because every listing resolves to one side or the other, the two values partition the inventory: their counts sum to the unfiltered total. As a filter, left/lhd and right/rhd are equivalent spellings and anything else is a 400. It is accepted by /api/search, /api/top-offers, /api/listVehicles and every facet endpoint — though on a facet endpoint it is computed live rather than read from the precomputed table, so it is slower than an unfiltered facet call.

Writing code that survives the differences

javascript
// Right: ask for the key, accept its absence, never branch on the source.
function conditionSummary(auction) {
  const d = auction.vehicle_details ?? {};

  return {
    // Present on auto1 and openlane; free text on ecarstrade; absent elsewhere.
    damages: d.damages ?? [],
    damageNotes: d.damage_comment ?? d.technical_issues ?? null,

    // ecarstrade is the only source with per-visit rows. Everyone else has a summary.
    serviceVisits: d.service_history ?? null,
    serviceSummary: d.service_history_summary ?? null,

    // Most listings carry no reports at all. Empty is normal, not an error.
    reports: d.inspection_reports ?? [],

    repairCost: d.estimated_repair_costs ?? null,
  };
}

// Wrong: this breaks the day a source is added, and hides data today.
if (auction.site_name === "auto1") { /* ... */ }
The absence of a key is information about the auction house, not a failure of the request.
  • Never hardcode the source list. Read it from /api/sites at startup. An unknown slug is a 400 naming the offender, so a stale hardcoded list turns a new source into a broken deploy.
  • Design for the shallowest source you serve. If your product promises "full service history on every car", only eCarsTrade can keep that promise. Promise it where it exists and degrade gracefully where it does not.
  • Treat car_identification as unversioned. Its keys follow each upstream's own naming and change when the upstream changes. Anything you depend on long-term should come from the common core or vehicle_details.
  • details_pending: true is not an error. It means the detail payload has not been assembled yet. Poll rather than retrying in a tight loop, and render the card data you already have.