Automotive · Applied ML

A used-car price range you can actually check.

Carmark takes a make, model and year and returns a fair-price range drawn from 180,975 real market listings — not a single guessed number. Free, public and built to be found.

valuation · held-out test setn = 30,786

MEDIAN ABSOLUTE PERCENTAGE ERROR

5.97%

P05MEDIANP95
35.8%median band width90.39%coverage · 0.39pp gap

5.97%

Median absolute percentage error

90.39%

Interval coverage against a 90% target

180,975

Market listings behind every estimate

~$10

Monthly infrastructure cost

The engineering judgment

A confidence claim the model can keep.

Quantile regression has a well-documented failure mode: the intervals it learns come out systematically too narrow. Asked for a 90% interval, Carmark’s raw quantile output contained the true price 85.24% of the time — a band that looks tighter, and therefore more impressive, precisely because it is wrong more often than it admits.

Raw quantile output85.24%
After conformal calibration90.39%

Empirical coverage against a 90% nominal target · gap 0.39pp

A conformal calibration layer, fit separately per price band, widens the intervals by exactly the amount the held-out data says they were short. Coverage lands at 90.39% against the 90% target — a gap of 0.39 percentage points.

When Carmark says it is 90% confident, it is right 90% of the time. Most valuation tools cannot make that claim, because most never measure it. An uncalibrated model produces a narrower band and a better-looking demo; a calibrated one produces a band a buyer can negotiate against.

The model

Three percentiles, learned jointly.

The estimator is a CatBoost gradient-boosted ensemble trained under a MultiQuantile loss at alpha 0.05, 0.50 and 0.95. The lower bound, median and upper bound are learned in a single model rather than three independent ones, so the percentiles cannot cross and the band stays internally consistent.

Iterations

2,000

Depth

8

Learning rate

0.05

Early stopping

100

51 features, 15 categorical

Categorical handling is left to CatBoost’s native encoding rather than pre-hashed into anonymity.

makemodelvariantenginetransmissionassemblyfuelcityconditionyearmileageprevious owners
A 715-entry model-family mapNameplates fragment across trims and market names. A hand-built family mapping groups them, so a thinly listed variant borrows signal from its family instead of being priced on a handful of rows.
Description-parsed flags, with negation handlingAccident history rarely appears in a structured field — it appears in prose. Flags are parsed from listing descriptions with negation handling, so “no accident history” is not read as an accident.

Accuracy holds across the price ladder

Evaluated on a held-out test set of 30,786 listings, broken out by price band so a single aggregate figure cannot hide a weak segment.

Median absolute percentage error by price band (PKR)
Price bandListingsMedian APE
Under 1M5,17510.11%
1M – 3M12,4016.36%
3M – 10M11,8104.39%
Over 10M1,4006.80%

Error is lowest through the 3M–10M band at 4.39%, where listing density is highest. It widens to 10.11% below 1M, where condition and history dominate price more than specification does, and to 6.80% above 10M, where only 1,400 comparable listings exist.

The data

A market corpus, not a sample.

Estimates are grounded in real listings across the Pakistani market, spanning model years 1980 to 2026.

180,975

Market listings

91

Makes

770

Models

395

Cities

885,976

Listing photos

191,083

Price-history records

The 191,083 price-history records matter more than the headline listing count: they capture the same vehicle repricing over time, which is what separates an asking price from a market price.

Architecture

Built so the model keeps serving.

Frontend

  • Next.js 16.3
  • React 19.2
  • TypeScript

Backend

  • FastAPI
  • SQLAlchemy
  • Alembic

Data

  • PostgreSQL 18
  • CatBoost artifact
  • Conformal sidecar

Infrastructure

  • EC2 t4g.small
  • Docker Compose
  • Caddy · auto TLS

The model loads once

CatBoost deserialization is expensive; prediction is the hot path. The model is held as a module-level singleton and scoring is batched into a single call, so the cost is paid at boot rather than per request.

Calibration travels with the artifact

Conformal deltas and the family map ship in a sidecar beside the model file, so a previously trained model keeps serving correctly as new features are added.

Codebase

Roughly 9,200 lines of Python and 7,600 of TypeScript, with 46 test files.

~9,200 Python~7,600 TypeScript46 test files

Discovery

Eleven hundred pages, each one an answer.

People do not search for a valuation tool. They search for a specific car in a specific year. Carmark generates 1,140 programmatic URLs — make hubs, model hubs and year-cohort price reports — so each of those searches has a page that answers it directly.

1,140

Programmatic URLs

1,237

Year cohorts, rendered on demand

6 hrs

Incremental static regeneration cache

16 hrs

From verification to Google index

Cohorts render on demand

Prebuilding all 1,237 year cohorts would saturate the API on every deploy. Incremental static regeneration renders each cohort on first request and caches it for six hours, so build time stays flat as coverage grows.

Structured data on every page

Schemas ship with each page rather than on the homepage alone. Google indexed the site within 16 hours of verification.

OrganizationWebSiteWebPageBreadcrumbListFAQPage

Infrastructure

One small ARM instance.

The whole platform — database, API, frontend and TLS termination — runs on a single EC2 t4g.small: ARM Graviton, 2 vCPU, 2GB RAM, roughly $10 a month.

Deployment is a single command. The build is sequenced so the frontend prerenders against a live API rather than failing against a cold backend — the ordering problem that makes most compose-based deploys flaky on a fresh host.

docker compose · t4g.smallrunning
  • Postgres18
  • FastAPImodel singleton
  • Next.jsISR · 6h
  • Caddyautomatic TLS

From the client

“AsterickLabs is a reliable engineering partner. Their team understands complex product requirements, delivers high-quality work, and communicates with the clarity and ownership you want from a long-term technology partner.”
MehranCTO, Carmark

Data-heavy product, taken end to end.

A 180,975-listing corpus, a jointly trained quantile model at 5.97% median error, a calibration layer that makes its confidence claim verifiable, 1,140 pages built to be found, and the whole thing serving from one $10-a-month instance.

Carmark launched days ago. The only external result worth quoting yet is that Google indexed it within 16 hours of verification. Everything else on this page is measured, not projected.