Market intelligence
Precomputed price snapshots for a brand, model, and year window — one for the Bulgarian retail market, one for our own auction inventory. Scope: market. Neither is enabled on a new key by default; ask for them. Both are read-only lookups into snapshots built by a pipeline on its own schedule. A 404 therefore means "no snapshot exists for that window", which is the normal answer for a thin brand/model/year combination — not an error to retry. Neither route carries envelope metadata; read X-Request-ID from the header.
Cars.bg Bulgarian retail market snapshot.
Requires the market scope.
Parameters
brand / makestring · query stringrequiredBrand name. Either spelling. Resolved through a fuzzy brand matcher, so display names work.
Example BMW·Where the value comes from /api/brands -> brands[].name
modelstring · query stringrequiredModel name. Resolved to one or more catalogue model ids.
Example 320d·Where the value comes from /api/models?brand=bmw -> models[].name
yearinteger · query stringrequiredThe centre year.
Example 2019·Where the value comes from Centre year chosen by your application.
flexinteger · query stringYear tolerance ± (0–10, default 1). A value outside that range is a 400.
Example 2·Where the value comes from Tolerance chosen by your application.
Example requests
GET https://api.thecarapi.com/api/cars-bg-market?brand=BMW&model=320d&year=2019GET https://api.thecarapi.com/api/cars-bg-market?make=Audi&model=A4&year=2020&flex=2Example response
{
"success": true,
"snapshot": {
"brand_id": "12",
"model_ids": [
"4411"
],
"year_center": 2019,
"year_flex": 2,
"year_from": 2017,
"year_to": 2021,
"listing_count": 84,
"avg_price_eur": 24310.5,
"median_price_eur": 23900,
"min_price_eur": 15500,
"max_price_eur": 41000,
"offers": [],
"raw_matches": [],
"computed_at": "2026-08-27T02:14:11",
"updated_at": "2026-08-27T02:14:11"
}
}What you get back
year_from / year_tointegerThe window year ± flex actually resolved to.
listing_countintegerHow many retail listings the aggregate is built from. Read this first — a median over four cars is not a market price.
avg_price_eur / median_price_eur / min_price_eur / max_price_eurnumberEUR aggregates as JSON numbers. Prefer the median; retail asking prices have a long right tail.
offersobject[]The listings behind the aggregate.
raw_matchesobject[]Everything the model matcher considered, including rows the aggregate excluded. Useful for auditing a surprising number.
computed_at / updated_attimestampWhen the snapshot was built. It is not recomputed per request.
Auction-market price snapshot for the same brand, model, and year window.
Requires the market scope.
Parameters
brand / makestring · query stringrequiredBrand name. Matched against the normalized clean_make.
Example BMW·Where the value comes from /api/brands -> brands[].name
modelstring · query stringrequiredModel name. Matched against clean_model.
Example 320d·Where the value comes from /api/models?brand=bmw -> models[].name
yearinteger · query stringrequiredThe centre year.
Example 2019·Where the value comes from Centre year chosen by your application.
flexinteger · query stringYear tolerance ± (0–10, default 1).
Example 2·Where the value comes from Tolerance chosen by your application.
scopeenum · query stringDefault all. Anything else is a 400. Each is a separately built snapshot, so active can exist while inactive does not.
Example active·Where the value comes from Choose all, active, or inactive.
Example requests
GET https://api.thecarapi.com/api/auction-market?brand=BMW&model=320d&year=2019&scope=activeGET https://api.thecarapi.com/api/auction-market?brand=Kia&model=EV6&year=2023&flex=1Example response
{
"success": true,
"snapshot": {
"clean_make": "BMW",
"clean_model": "320d",
"year_center": 2019,
"year_flex": 1,
"year_from": 2018,
"year_to": 2020,
"scope": "all",
"auction_count": 412,
"avg_price_eur": 18220.4,
"median_price_eur": 17800,
"p10_price_eur": 11900,
"p25_price_eur": 14750,
"p75_price_eur": 21400,
"p90_price_eur": 26100,
"min_price_eur": 6200,
"max_price_eur": 44900,
"first_seen_min": "2026-01-04T00:00:00",
"first_seen_max": "2026-08-22T00:00:00",
"auctions": [],
"computed_at": "2026-08-27T02:41:03",
"updated_at": "2026-08-27T02:41:03"
}
}What you get back
scopeenumEchoes the request: active restricts to lots still open, inactive to closed ones, all covers both.
auction_countintegerLots behind the aggregate. Sanity-check it before quoting a percentile.
p10_price_eur / p25_price_eur / p75_price_eur / p90_price_eurnumberPercentiles — the reason to prefer this over the Cars.bg snapshot when you want a spread rather than a point estimate. A wide p10–p90 band means the specification is not pinning the price down.
first_seen_min / first_seen_maxtimestampThe observation window the lots span. A snapshot whose window is eight months wide is not a spot price.
auctionsobject[]The individual lots the aggregate was computed from.