Fields by source
What each supported inventory source actually publishes — the condition-data coverage matrix, the source-specific traps, and how to write code that survives the differences.
Supported inventory 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; Korean listings carry specifications and optional condition evidence. 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.
| Layer | Where | Consistency | Use it for |
|---|---|---|---|
| The common core | Search result cards and the top level of both detail endpoints | Identical across all supported sources | Listings, filters, sorting, price display, countdowns — anything that has to work uniformly. |
| The normalized detail block | vehicle_details on /api/auction/{site}/{id} and /api/car-details | Same key names everywhere; presence varies by source | Condition, damages, documents, service history, equipment. Check for the key, do not assume it. |
| The raw source map | car_identification | Source-specific. Key names change with each upstream | The 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.
| Source | What it is | Depth | What only it gives you |
|---|---|---|---|
auto1 | Europe's largest digital B2B wholesale marketplace | Deep — full vehicle_details | The richest equipment data in the API (DAT catalogue), paint-thickness measurements, wheel condition, structured damages with a summary and prior-damage history. |
openlane | Pan-European ex-lease and fleet auctions | Deep — full vehicle_details | Per-damage free-text comments, typed report PDFs (internal damage, external damage, maintenance, battery health) and its own report index in car_reports. |
schadeautos | Netherlands and Benelux salvage and repairable stock | Moderate | Salvage-focused fields: engine capacity, transmission, VAT/margin status, net and gross export pricing, narrative damage text. |
copart | Copart Germany salvage and run-and-drive lots | Moderate | Run-and-drive signal, build-sheet series and special equipment, published lot prices; no at-request live-price overlay. |
encar | South Korea's dominant vehicle marketplace | Moderate — deep specs, shallow condition | A large specification and options block, photo counts grouped by type, and registration data. Condition and accident detail is thinner than the EU sources. |
kbchachacha | South Korean cash-sale marketplace | Specs and optional inspection evidence | vehicle_details.kb_diagnosis / kb_inspection: status, report rows, checked controls, panel marks, images and VIN when present. |
japan | Japanese export inventory from 127 auction houses (USS, JU, TAA, CAA, ARAI, Honda and others) | Shallow — expect vehicle_details sparse or absent | Imported photos, optional sheets and grades, originating sale information and matched reseller offer evidence. No on-demand detail fetcher. |
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 current integration does not promise that field. It may be unavailable upstream, not yet enriched, or omitted by permissions; absence is not a clean-condition verdict.
auto1 | openlane | Other sources | |
|---|---|---|---|
damages (per panel) | Structured, with summary, count and prior damages | Structured, with a comment per damage | Sparse or absent |
inspection_reports | One URL | Typed PDFs by type_id | KB uses kb_diagnosis / kb_inspection. Japan sheets are optional imported evidence. |
documents | Service book + service-detail images | None — paperwork booleans only | — |
service_history | Summary only | Summary only | — |
equipment | DAT catalogue (richest) | Option list + accessories | Varies |
paperwork | Partial | COCAvailable, RegistrationDocsAvailable, IsV5Present, LicensePlate | — |
estimated_repair_costs | Yes | Yes | — |
Source-specific notes worth knowing
Japanese auctions — the price is an opening bid
A live Japanese lot has no hammer price until it closes, so current_price on japan is the opening bid, not a cost. Some lots publish no opener, and conflicting imported prices are withheld. Nominal starters can be far below the eventual price. 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.
Japanese rows carry origin JP. Use country=JP or site=japan, and /api/auction/japan/{id} for stored details. /api/car-details does not accept Japan. Use the string id from search without converting it to a JavaScript number.
OpenLane — report types
OpenLane classifies each report it publishes. type is the readable name and type_id the source's raw code.
type_id | type | Appears in |
|---|---|---|
| 1 | internal_damage_report | inspection_reports |
| 2 | external_damage_report | inspection_reports |
| 3 | maintenance_records | inspection_reports |
| 4 | option_report | option_reports |
| 5 | battery_health_report | inspection_reports |
| other | report | inspection_reports |
Auto1's single inspection report is normalized into the same list with type inspection_report and no type_id.
Japanese auctions — the auction sheet
Japanese auction sheets and photos are optional imported evidence. Use the returned gallery and available report entries; the current importer does not promise a normalized auction_sheet entry on every lot, an extracted VIN, or live upstream detail fetching. The source specification and matched reseller evidence remain under car_identification; imported sheet URLs are under JapanMerged.AuctionSheetUrls.
Opening and downloading reports
Follow the exact returned /report-vault/{site}/{auction_id}/{token} URL; the token identifies an already-known report and is not an upstream URL you can construct. This delivery route currently needs no API key. A successful response is a binary file with its Content-Type, not a JSON envelope. download=1 requests an attachment. A 302 points to an upstream page; a 400 means an invalid token, a 404 means no matching report, and a 503 means the backing database is unavailable. Do not forward your API key to an upstream redirect target.
KB ChaChaCha — diagnosis and inspection
Read vehicle_details.kb_diagnosis and vehicle_details.kb_inspection independently: one report can be available while the other is unavailable. They preserve the source evidence rather than turning it into a universal accident score. Use the numeric carSeq for /api/car-details?site=kbchachacha&id=..., or the exact stored identifier from a search card for /api/auction/kbchachacha/{id}.
| Report field | Shape | How to use it |
|---|---|---|
status | available or unavailable | Unavailable means there is no usable report; it does not mean no damage. An absent block may also mean details have not been fetched. |
rows | {cells, cells_en}[] | Ordered table rows with original and translated cells. Preserve row order and repeated labels rather than converting to a dictionary. |
checked_controls | {name, id, value, label}[] | Selected controls on the source report. Keep the associated label; a raw checked value alone is not a diagnosis. |
panel_marks | {position, panel, code, condition}[] | X replacement, C corrosion, W panel repair/welding, A scratch, U unevenness, T damage. Source position and diagram panel number differ. Some marks instead carry element_id and condition_original from the source diagram. |
images / documents | arrays | Optional visual evidence and document records. Use returned URLs; these nested links are not uniformly rewritten through the report vault. |
vin | string or null | Present only when a valid VIN is extracted. Missing VIN is not evidence that two listings are different vehicles. |
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 — 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 normalized to left or right. Explicit source evidence is used where supported; otherwise it is inferred from registration market. It is an inferred field where no explicit source value exists, not a universal physical inspection guarantee. Japanese imports may include left-hand-drive vehicles, so do not derive steering from country in your client.
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 it takes two values, each with four equivalent spellings — left, lhd, left-hand, left_hand and right, rhd, right-hand, right_hand — 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
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") { /* ... */ }- Never hardcode the source list. Read it from
/api/sitesat startup. An unknown slug is a400naming the offender, so a stale hardcoded list turns a new source into a broken deploy. - Design for the shallowest source you serve. No source guarantees full service history on every car. Promise it where it exists and degrade gracefully where it does not.
- Treat
car_identificationas 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 orvehicle_details. details_pending: trueis 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.