One unified API for normalized inventory, CDN images, damages, market signals, price history, and past auctions from Auto1, OpenLane, Schadeautos, Copart DE, eCarsTrade, Encar and KB ChaChaCha, and Japanese auctions — plus 9.8M European retail classifieds listings from 681 portals across 39 countries. Skip custom indexing pipelines and proxy bans.
Plus European Classifieds — 9.8M retail listings from 681 origin portals across 39 European countries.
Interactive playground
Over one million live vehicles. One API.
Each platform publishes condition sheets differently. TheCarApi normalizes make, model, fuel, price, and damage — plus a 50M+ image vault on CDN. Stable identity site/auction_id.
500K+ top-offer signals, auction comps, and retail prices from 681 EU classifieds portals
Price history
Track source and public price changes for each auction
Beyond the raw feed
What the sources do not publish
Copying fields off eight auction sites gets you eight inconsistent feeds. These four are the gaps we close before the data reaches you — a missing VIN, a car listed twice, the lots that already ended, and the same vehicle seen across sources and over time.
Auto1
A VIN where the source publishes none
Auto1 states no chassis number anywhere in its payload — but it photographs the registration certificate.
We read the VIN off that paperwork. Opening an Auto1 detail queues the car, an OCR worker reads the document photos, and the answer comes back on the next read as vin_ocr — the number, a confidence, and the evidence photo it came from. A confident read also fills chassis_number, so a client that only knows about that field gets the VIN for free.
41% of Auto1 cars with a document photo end up with a published VIN
vin_ocr: { vin, confidence, evidence } — plus vin_ocr_pending while a read is in flight
Only a high-confidence read is presented as the car’s chassis number
Ceiling is upstream, not ours: Auto1 blurs the VIN field on ES, IT and PT certificates
The same Korean car is listed on Encar and on KB ChaChaCha, at two different prices, with two different photo sets.
Ingesting both sources naively doubles your Korean inventory and makes every count wrong. We match the two listings on VIN, or on a corroborated licence plate with make and model — never on specification alone, because forty identical Sonatas are not one car. The duplicate is hidden, one representative card is published, and both asking prices stay attached to it.
match_method tells you which evidence grouped the car: vin or plate_make_model
source_comparison.offers carries every listing for the car with its own price and link
spread_eur is what the same car costs on the cheaper source — the number that pays for the lookup
Photo sets are never interleaved; image_source names the listing the gallery came from
Live inventory tells you what is for sale. It cannot tell you what a 2019 Golf actually went for, or that this car has been round the block twice.
500K+ ended lots are kept with their stored detail and an archived_at stamp, searchable on the same filters as live inventory and addressable by the same site + id pair. Query it by archive date window or by full VIN, and read /api/archive/stats for per-source coverage before you build on a field.
Same filter vocabulary as /api/search, plus archived_from, archived_to and vin
Per-source coverage counts for price, reported final price and VIN
A last observed price is not a confirmed sale price — and we say so in the response
Archived rows are never rewritten, so they cache for an hour
A car that fails to sell and is relisted looks like two vehicles. A car re-exported two years later looks like a new one.
Look a full VIN up across live and archived inventory and get back every auction appearance we hold, newest first, deduplicated on source and auction id. Two rows for one VIN months apart, with different mileages, is the pattern worth surfacing to a buyer — and the one that stops a pricing model counting the same car twice.
Up to 100 appearances per VIN, each flagged live or archived
Mileage and price per appearance, so a rollback is visible
A VIN we have never seen answers 200 with match_count: 0, not an error
Sensitive endpoint — ask for the grant rather than assuming it
Built for product traffic: low-latency reads, aggressive caching, continuous source sync, and transparent health endpoints — so your apps stay fast when inventory moves.
8
Inventory sources
Europe, Korea and Japan
7
Combined facets
One request for flat dimensions
2026-09-03
Schema contract
Machine-readable reference
Per source
Inventory freshness
Full refresh cycle
Edge-friendly caching
Many GETs cache 60–300s with X-Cache headers. Revalidate with ETag and inspect X-Cache rather than assuming a hit.
Continuous multi-source sync
Indexing pipelines keep Auto1, OpenLane, Schadeautos, Copart DE, eCarsTrade, Encar, KB ChaChaCha and the Japanese auction houses fresh through scheduled ingestion and detail enrichment, alongside the European classifieds feed, without you running proxies or parsers.
Observable by design
GET /api/health and contract versioning, X-Request-ID tracing, and auth lockouts protect uptime under bad-key storms.
We keep eyes on Auto1, OpenLane, Schadeautos, Copart, eCarsTrade, Encar, KB ChaChaCha, the Japanese auction houses and 681 EU classifieds portals so your engineers do not babysit proxies.
Building in-house indexing
Indexing vehicle lots is a moving target. Layout changes, bans, and storage overhead are constant drag.
✕Residential proxy overhead: High monthly proxy spend to bypass IP limits.
✕Constant rebuilds: Every platform update breaks selectors and stalls inventory.
✕Zero standardization: Thousands of lines to unify eight source schemas plus classifieds.
✕Anti-bot walls: Cloudflare challenges pause sync without ops coverage.
Using TheCarApi
Production multi-source inventory + query API. We handle ingestion; you ship product.
✓Image vault: 50M+ CDN WebP — no image pipeline to run.
✓Discovery tools: Live facets, catalog pages, SEO helpers, and EU retail comps from 39 countries.
✓History depth: 5M+ vehicles in main table + 500K+ archived.
1M+
Live vehicles
5M+
Vehicles ever indexed
50M+
Images in vault
500K+
Deal signals
One plan. Unlimited access.
A single flat price for the full API: search, detail, images, facets, catalog, SEO, and archive access. Up to 200,000 requests a month and no feature gates.
Evaluate the API with a temporary key — perfect for demos, investor showcases, and proof-of-concepts. Create an account, confirm your email and your free trial key is issued instantly; no card required.
Do you provide bidding accounts or purchase rights on Auto1, OpenLane, Copart, eCarsTrade, etc.?
No. TheCarApi is a data and inventory API. We expose normalized search, detail, images, catalog data, and market signals. Bidding and purchasing require your own credentials with each platform.
How do I authenticate?
Send your API key via X-API-Key header or Authorization: Bearer <key>. Query-string api_key is optional and only if enabled server-side. Invalid keys return 401; repeated failures lock out the IP (5 fails / 5 min → 15 min lockout).
What is the stable public identity for a vehicle?
Always persist site_name + auction_id_str (e.g. auto1/48291033), preserving the id as a string. Numeric-only legacy IDs can collide across sources and return HTTP 409 on ambiguous endpoints.
How large is the public inventory vs full database?
Public inventory is 1M+ live vehicles across Auto1, OpenLane, Schadeautos, Copart DE, eCarsTrade, Encar, KB ChaChaCha and the Japanese auction houses. Full indexed history exceeds 5M vehicles with 500K+ archived for historical / delta products. The 9.8M European retail classifieds listings are counted separately — they are a market-reference dataset, not auction inventory.
What is the European Classifieds Network and why is it not a site value?
It is 9.8M retail listings gathered from 681 classifieds portals, dealer sites and manufacturer stock pages across 39 European countries — asking prices, not auctions. Because those rows have no bidding, no auction end date, no detail payload and no gallery (one remote thumbnail per listing), they live in their own tables with their own vocabulary (seller type, origin portal). They are never merged into /api/search and never appear in /api/sites. Query them at /api/classifieds/listings, /api/classifieds/facets and /api/classifieds/models under the classifieds scope (theparking remains a legacy alias).
Is eCarsTrade a full source like the others?
Yes. eCarsTrade behaves like every other auction source: it is a valid site value for /api/search, /api/auction/{site}/{id}, /api/car-details, and the import calculator site_name fee model. Detail payloads are full; the gallery arrives under the ImageUrls key of car_identification.
How do I read condition, damages and paperwork without branching per source?
Use the vehicle_details block on /api/auction/{site}/{id} and /api/car-details. Each auction house names the same concepts differently — a downloadable file is Documents[] on Auto1 but ECarsTradeDocuments[] on eCarsTrade, while Documents on OpenLane is a dict of paperwork booleans and not a file list at all — so vehicle_details normalizes condition, documents, inspection reports, service history, equipment, warranty, specs and location into one shape. Coverage is not uniform: eCarsTrade has no per-panel damage list upstream, OpenLane publishes no document files, and only eCarsTrade has per-visit service rows. Normalized report URLs are served through /report-vault and cached; unsupported hosts or non-file pages can redirect upstream. Raw per-source data stays in car_identification.
Why do detail payloads not include auction fees, transport or delivery costs?
Because those figures are quoted to our buyer account and our delivery address, not yours — OpenLane gates them behind per-account visibility flags, Auto1 prices routes from our merchant profile, eCarsTrade quotes to our warehouse. Publishing them next to a public price would also expose our markup by subtraction. Fee, bid-history, transport and delivery blocks are stripped at the response boundary, along with anything identifying our account on a platform. Still served: the auction house’s own published asking prices, VAT scheme, estimated repair cost, and the seller/warehouse location. For landed cost, use the import calculator, which prices your own route.
How fresh is the data, and how do live prices work?
There are two kinds of price and it is worth knowing which one you hold. Every listing — spec, condition, availability and price — is refreshed by the scheduled ingestion pipeline; that is its cycle price, and for a fixed-price listing, a buy-now car or a lot that is not taking bids it is simply its price. The exception is a running auction with open bidding on openlane or ecarstrade: for those the bid is read from the auction house at the moment you request the car detail, and the response carries a live_price block. There is no separate real-time endpoint, no parameter to switch on and no premium tier for it. Search results, facets and top offers are never live-priced — they serve cycle prices, which is what makes them fast enough to page through. An absent live_price block is not an error; read live_prices from /api/contract to tell "live prices are unavailable" from "this car has none right now".
Do you provide CO2 emissions data?
Yes, in two clearly separated fields. co2 is the measured figure the auction house published, present on roughly half of EU lots. co2_estimated is derived for lots that publish none, and is never a measured value — an estimate must not be able to masquerade as a measurement. Because EU registration documents switched from NEDC to WLTP on 1 January 2021 and the same car reads 12-25% higher under WLTP, every estimate ships with co2_estimated_standard telling you which cycle it is on. Estimates are EU-market sources only: Korean, Japanese and American lots are homologated on different cycles, so no EU figure exists for them.
Does every source give the same fields?
No, and this is worth checking before you scope a feature. Auto1, OpenLane and eCarsTrade publish deep condition data; Schadeautos, Copart and Encar are moderate; the Japanese auction feed is shallow and its vehicle_details is often sparse or absent. Only eCarsTrade has per-visit service history rows. Only Auto1 has paint measurements and the DAT equipment catalogue. OpenLane publishes no document files at all, only paperwork booleans. The common core — identity, make/model/year, fuel, gearbox, mileage, prices, steering, images — is consistent everywhere. The Fields by source page in the documentation carries the full coverage matrix.
Are images included?
Yes. Search cards carry thumbnail_url, and the full ordered gallery arrives on the auction detail response as vault_gallery — the exact body GET /api/auction-images/{site}/{id} returns, so a detail page is one request rather than two. Each entry carries a URL that works right now: served_url once the photo is stored on our CDN, remote_url until then, plus image_status, dimensions and a pending count for photos still landing. Stored photos are AVIF or WebP depending on what the source served, so rely on the URL and content type rather than the extension, and use a client that follows redirects — /image-vault/* paths answer with a 302 to a pre-signed object URL.
What is normalized vs raw?
Three layers. The common core — identity, make/model/year, fuel, gearbox, mileage, prices, steering, images — is identical across all eight sources and is what search cards carry. vehicle_details on the two detail endpoints is the normalized condition and paperwork block: same key names everywhere, presence varying by source. car_identification is the raw source-specific spec map, returned on auction detail as well; its keys follow each upstream own naming and change when the upstream changes, so prefer vehicle_details for anything you depend on long-term.
Is rate limiting enforced?
Yes. A managed key can carry fixed-window quotas on any of four periods — minute, hour, day and month — and the tightest configured window is reported as X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A key issued with no quota sends none of those headers: their absence means unlimited, not limit reached. A breach returns 429 with Retry-After; honour it rather than backing off on a schedule of your own. Windows are fixed rather than sliding, so a burst across a window boundary is expected. Five failed authentications from one IP trigger a 15-minute brute-force lockout, also a 429, including requests that then carry a valid key. Contact us for production quotas.
Can I access historical / archived lots?
Use /api/archive/search, /api/archive/auction/{site}/{id}, and /api/archive/stats with an archive scope grant. Coverage and final-price availability vary by source; last observed prices are not confirmed sale prices.
Auto1 publishes no VIN. Do I get one anyway?
Usually. Auto1 states no chassis number in its payload but photographs the registration certificate, so we read the VIN off that paperwork with OCR. Opening an Auto1 detail queues the car and the answer arrives on the next read as vin_ocr — { vin, confidence, evidence } — with vin_ocr_pending: true meanwhile, exactly like the live-price flag. A high-confidence read also fills chassis_number, so a client that only reads that field gets it without changing anything. About 41% of Auto1 cars with a document photo end up with a published VIN; the ceiling is upstream, because Auto1 blurs the VIN field on Spanish, Italian and Portuguese certificates. Only a confident read is presented as the car’s identity — a weaker one rides along labelled rather than silently asserting a VIN one OCR pass produced.
Encar and KB ChaChaCha list the same cars. Do I get duplicates?
No. The same Korean car is often listed on both marketplaces at two different prices with two different photo sets, and ingesting both naively doubles your Korean inventory. We group the listings on VIN, or on a corroborated licence plate together with make and model — never on specification alone, because similar specs are not an identity. The duplicate is hidden from search and one representative card is published, with both asking prices still attached: source_comparison carries every offer for that car with its own price and link, which source was selected, the spread_eur between them, the match_method that grouped them, and the image_source the gallery came from. Photo sets are never interleaved. Korean source totals are therefore not the sum of the two upstream websites. The merge metadata is a separate field grant — ask for korea_merge if you want to show the comparison yourself.
Can I track one car across sources and over time?
Yes, by VIN. /api/vin/{vin} returns every auction appearance we hold for a full VIN across live and archived inventory — up to 100, newest first, deduplicated on (source, auction id) so one lot never appears twice. Each appearance carries its own mileage, price and lifecycle timestamps and is flagged live or archived, so a relist, a re-export or a mileage rollback is visible rather than inferred. A VIN that is not 17 valid characters is a 400; a valid VIN we have never seen answers 200 with match_count: 0. It is a sensitive route and is not enabled on a new key by default — ask for it.