contract 2026-08-19
Status

Changelog

Every contract version and what moved in it. The version this deployment serves is on every response as contract_version, currently 2026-08-19.

2026-08-19feature2026-08-19

Contract version 2026-08-19 — combined facets, embedded galleries, gzip and conditional requests

  • Every change in this release is additive. No field changed type, no field was removed, no default changed, and no endpoint changed its response shape — an integration written against 2026-08-18 runs unmodified.
  • New GET /api/facets returns brands, years, fuels, countries, gearboxes and sites in one response, with fields= selecting the subset you render. Each field is its own endpoint’s payload merged verbatim, so a value means exactly what it means there. Scope search, and it bills one quota unit instead of six. models stays at /api/models — it is brand-scoped.
  • A facet dimension that cannot be served is reported under errors while every other dimension is returned normally, so one slow field cannot blank a filter sidebar. The per-dimension endpoints are unchanged and stay supported.
  • GET /api/search accepts is_active as the documented spelling of the ended-lot switch: is_active=true (the default) hides closed lots, is_active=false shows them in addition to live ones. It is not a filter on the is_active response field, and it does not return only ended lots. include_ended is the same switch inverted and is unchanged; if both are sent, include_ended wins.
  • GET /api/auction/{site}/{id} now embeds vault_gallery — the exact body of /api/auction-images/{site}/{id} (images, count, pending) — so a detail page is one request instead of two. images and gallery_images are untouched. Both routes read one cache entry and can never disagree, and while pending is non-zero both are served with max-age=10 so a polling client sees photos as they land.
  • Send Accept-Encoding: gzip and any response over 2 KB comes back gzipped — on the order of an eighth of the bytes on a full search page. Most HTTP clients negotiate this transparently; a few (notably PHP Guzzle in some configurations) need it enabled explicitly.
  • /api/search now carries an ETag, as the facet and catalog routes already did. Echo it back in If-None-Match and an unchanged page answers 304 Not Modified with no body. ETags are weak (W/"...") across the API by design, so one tag stays valid whether or not the body came back compressed — compare them as opaque strings.
  • GET /api/contract declares the new surface: schemas.auction_detail.optional lists vault_gallery, schemas.brands_models_facets.optional lists errors, and version reads 2026-08-19.
2026-08-18breaking2026-08-18

Contract version 2026-08-18 — price fields are JSON numbers

  • Price fields are now always JSON numbers. They were serialized as strings ("25600.00") on a normal read but as numbers (25600.0) whenever a live price had been refreshed — the same field, two types, depending on something a client could neither control nor predict. No change is needed if you parse with Number(...), float(...) or into a dynamic type; a statically typed client declaring them as strings has to retype them as numbers.
  • Affected fields: start_price, current_price, current_final, current_tax, current_tax_delivery, buy_now_price, buynow_final, buynow_tax, buynow_tax_delivery, final_price, public_price_eur, current_bgn and buynow_bgn.
  • /api/car-details now returns the price fields. It previously returned none of them, so the two detail endpoints disagreed about what a car costs. They arrive under the same names at the top level of the response, because that body is source-shaped and has no auction wrapper. Purely additive.
  • New field live_price_pending: true means the upstream refresh missed the request budget and is still running — read once more after ~2s and stop. Those responses carry Cache-Control: no-store and X-Live-Price: pending, so a follow-up read is not answered from cache.
  • GET /api/contract declares the new fields: schemas.auction_detail.optional now lists the price fields, live_price and live_price_pending.
2026-08-17feature2026-08-17

Contract version 2026-08-17 — live prices on running auctions

  • A running openlane or ecarstrade auction now has its bid refreshed from the auction house while the request is served. There is no separate endpoint and no parameter to switch on: ask for the car the way you already do, and if it qualifies you get the current figure.
  • The at-request bid re-read applies to GET /api/auction/{site}/{id} and to GET|POST /api/car-details. Search, top-offers and every price-based sort or filter serve the live feed price without the extra per-request call, so a detail page can legitimately show a higher current_price than the search card it was opened from — that is the newer number, not an inconsistency.
  • A refreshed response carries a live_price block ({price, currency, source, fetched_at}) and has current_price, current_final, current_tax, current_tax_delivery and public_price_eur recomputed, so a client that ignores live_price still shows the right number. buy_now_price and buynow_final are never touched.
  • GET /api/contract gains a live_prices block ({enabled, sites, ttl_seconds}). Read it rather than hardcoding which sources support live prices, and use it to tell "this deployment cannot refresh prices" from "this car has none right now".
  • A refreshed price is reused for ttl_seconds (default 120) and Cache-Control: max-age drops to match. Polling faster than the TTL returns the same figure.
  • The classifieds listings feed gained source_exclude and include_total, and now reports total_capped (counting stopped at 100,000) and total_unavailable (the count did not finish its budget) alongside total. /api/theparking/facets gained limit and value_counts.
2026-08-14feature2026-08-14

Contract version 2026-08-14 — Japanese auctions, vehicle_details, account-scoped fields removed

  • Added the Japanese auction houses (USS, ARAI, AUCNET, BAYAUC, CAA) as a seventh source under the slug japanauction: a valid site value for search, auction detail, price history, images and car-details. For japanauction and auto1, /api/car-details takes the offer id/UUID rather than the numeric auction id.
  • Added the normalized vehicle_details block to /api/auction/{site}/{id} and /api/car-details — condition, documents, inspection reports, service history, equipment, warranty, specs and location, in one shape across sources. Omitted while details_pending.
  • /api/countries now returns JP. country=europe is an exclusion, not a list: it currently excludes KR (Encar) and JP (Japanese auctions), and rows with no recorded country are treated as European.
  • Account-scoped commercial data is now stripped at the response boundary: auction fees, bid history, transport and every delivery*/selfpickup* key, plus our buyer-account identity on each platform and internal processing metadata. Email addresses are redacted from free-text values. Published asking prices, VAT scheme, estimated repair cost and seller location are unaffected.
2026-08feature2026-08-06

European retail classifieds feed

  • Added /api/theparking/listings, /api/theparking/facets, and /api/theparking/models under the new theparking scope.
  • Retail classifieds aggregated from 681 origin portals across 39 European countries, with seller type and origin portal on every row.
  • Ended and paid-placement listings are excluded from every response.
2026-07feature2026-07-15

eCarsTrade added as an auction source

  • eCarsTrade is now a valid site value for search, auction detail, car-details, and the calculator fee model.
  • Galleries are exposed under the ImageUrls key of car_identification.
  • Published /api/top-offers with the market_reference each verdict was made against.
2026-06-10feature2026-06-10

Contract version 2026-06-10

  • Published contract version 2026-06-10 with pagination caps (limit 100, offset 5000).
  • Documented public-read site bypass for GET inventory, facets, catalog, SEO, images, health.
  • Documented search cards, auction details, galleries, catalog responses, and pagination limits.
2026-05improvement2026-05-20

Image vault & gallery API scale

  • Image vault past 50M+ ready WebP assets with CDN served_url on gallery endpoint.
  • Listings annotate ready vault URLs when available.
  • Encar async/sync image prefetch endpoints for on-demand boost.
2026-03feature2026-03-01

Multi-source public inventory

  • Unified public feed across Auto1, OpenLane, Schadeautos, Copart DE.
  • Normalized clean_make / clean_model / fuel_group / gearbox_group / public_price_eur.
  • Archive pipeline for inactive lots (full row + archived_at).