Guides

Building a used car marketplace without owning inventory

The hard part of a marketplace is never the listings page. It is having something to list on day one, and having a reason for anyone to use you rather than the source.

TheCarApi EngineeringPlatform teamPublished Updated 11 min read

Every marketplace starts empty, and an empty marketplace has no reason for anyone to visit, which means no sellers, which means it stays empty. In most categories you break that loop with sales effort. In vehicles you can sidestep it, because wholesale inventory already exists in volume and is reachable programmatically.

That solves the cold start and immediately creates the real question: if your listings come from the same feed anyone can license, what makes your product worth using? This walks through both — the architecture, and the part that has to be yours.

Decide what you actually are

Four viable shapes, with materially different technical requirements. Choosing late is expensive.

ModelYou provideRevenueHardest part
Discovery portalSearch and comparison, referral outReferral or subscriptionTraffic acquisition
BrokerageSearch plus you transact on the buyer's behalfCommission per dealOperations, trust, logistics
Dealer toolingSourcing and pricing for trade buyersSaaS subscriptionBeating a spreadsheet
Regional importerCurated foreign stock, landed prices in local currencyMargin per vehicleImport compliance

The discovery portal is the easiest to build and the hardest to sustain, because you are competing on SEO against the sources themselves. The regional importer is the opposite: real operational work, but a genuine reason to exist, because the buyer cannot access German or Korean wholesale supply directly and does not want to handle the import.

The data layer

The decision that shapes everything downstream: proxy the API on every request, or maintain your own copy?

Proxy-through

Your backend forwards search requests to the provider and returns the response. Nothing is stored. It is fast to build and always fresh, and it is the right starting point.

It stops working when you need to join provider data against your own — favourites, sold-by-you flags, custom pricing, per-vehicle notes — or when your traffic makes per-request calls expensive, or when you need search behaviour the provider does not offer.

Local mirror

You sync inventory into your own database and search it locally. More moving parts, and it introduces a staleness window you now own — but it lets you rank, join and enrich freely.

Whichever you choose, key everything on the source pair. Your favourites table stores openlane/11125938, not a synthetic id that will not survive a resync.

sql
create table saved_vehicle (
  id            bigserial primary key,
  user_id       bigint not null references app_user(id),
  site_name     text   not null,   -- openlane | auto1 | encar | ...
  auction_id    text   not null,   -- the platform's own lot id
  saved_at      timestamptz not null default now(),
  -- denormalized so a saved list still renders after the lot closes
  title_snapshot     text,
  price_eur_snapshot numeric(12,2),
  unique (user_id, site_name, auction_id)
);
Snapshotting title and price is not redundancy — it is what stops a user's saved list turning into a page of dead references once lots close.

Search is your product

Users judge a vehicle marketplace almost entirely on search. Four things carry most of the perceived quality:

  1. 1Facet counts that are live. A filter option showing zero results, or showing results that do not exist, destroys trust faster than any other defect. Drive facets from the API rather than a static list.
  2. 2Sensible defaults. Newest-first or best-value-first beats a raw price sort, which surfaces the least desirable stock at the top of every page.
  3. 3Fast pagination. Counting total matches is often the most expensive part of a search. On infinite scroll, request include_total=false and skip it.
  4. 4Stable ordering under randomisation. If you shuffle results for variety, use a seed so page two does not repeat page one.
bash
# Page 1 — note the returned random_seed
curl -s "https://api.thecarapi.com/api/search?sort=random&limit=24&include_total=false" \
  -H "X-API-Key: $API_KEY"

# Page 2 — pass the seed back so the ordering stays consistent
curl -s "https://api.thecarapi.com/api/search?sort=random&seed=k9f2ab\
&limit=24&offset=24&include_total=false" \
  -H "X-API-Key: $API_KEY"

Build the filter UI from the catalog endpoints rather than hardcoding brand and fuel lists. Source vocabularies drift, and a hardcoded value that changes upstream fails silently as an empty result set — the worst kind of bug, because it looks like a market condition.

Images decide how the product feels

Rules that matter more here than in most product categories, because the listing grid is the product:

  • Thumbnail only on search cards. Never fetch galleries for a results page.
  • Set explicit width and height so the grid does not reflow as images arrive.
  • loading="lazy" below the fold; eager for the first row.
  • Generate alt text from the vehicle data you already have — it is free accessibility and free image SEO.
  • Never hotlink source URLs. They expire and are hotlink-protected, and the failure is delayed enough to reach production.

The part that has to be yours

If your entire product is a nicer frontend over a feed, your competitive position is a design refresh away from disappearing. The defensible layer is always something the feed cannot contain:

  • Landed cost in the buyer's currency and jurisdiction. Transport, duty, VAT, registration, your fee — one number a buyer can act on. Genuinely hard, genuinely valuable, and specific to a market you understand.
  • Curation. Rejecting 95% of available stock is a service. "Every car in Europe" is not a value proposition; "the forty cars worth your attention this week" is.
  • Trust infrastructure. Escrow, inspection, delivery, a real company with a real address. This is the entire product for cross-border buyers.
  • A proprietary signal. Your own repair-cost model, your own local demand data, your own dealer network's bid history.
  • Workflow. For trade buyers, integration into how they actually work — CRM, stock management, alerts on saved searches — beats a better search box.

Nobody wins a market by showing the same listings as everyone else, slightly later. The feed is the floor you build on, not the building.

A launch sequence

  1. 1Week 1 — proxy search and detail straight through. No database, no auth. Prove the funnel: do people search, and do they click?
  2. 2Week 2–3 — accounts, saved vehicles, saved searches. This is the first thing that makes returning worthwhile.
  3. 3Week 4–6 — the mirror, if search performance or joins demand it. Not before.
  4. 4Week 6+ — the defensible layer. Landed cost, curation, or whichever of the above fits your market.
  5. 5Continuously — SEO. Vehicle marketplaces live on organic search, and that means server-rendered listing pages with real URLs, not a client-only app. See how we handle it.

For the integration mechanics — pagination, caching, retries, rate limits — the integration guide covers the details, and the API reference documents every endpoint used here.

Frequently asked questions

Can I build a car marketplace without owning any vehicles?

Yes — it is the standard way to solve the cold-start problem in this category, because wholesale inventory already exists in volume and is reachable programmatically. The consequence is that inventory stops being a differentiator, so the product needs something the feed cannot supply: landed cost, curation, trust infrastructure, or workflow integration.

Should I mirror the inventory into my own database or proxy the API?

Start by proxying — it is faster to build, always fresh, and lets you validate the product in days. Move to a mirror only when a specific need forces it: joining against your own data, ranking the provider does not offer, or per-request cost at your traffic level. A common middle ground is mirroring search-card fields while fetching detail and images live.

What should I use as the primary key for vehicles?

The source platform slug together with the platform's own lot id — for example openlane/11125938. It is stable, survives resyncs, and is what every detail, image and price-history endpoint is addressed by. Also snapshot the title and price in tables like saved vehicles, so a user's list still renders after the underlying lot closes.

How do I compete with the auction platforms themselves?

Not on inventory, since it is the same stock. Compete on something the source cannot offer: landed cost in the buyer's currency and jurisdiction, curation that rejects most of the catalogue, trust infrastructure for cross-border purchases, or workflow integration for trade buyers. Access to supply the buyer cannot reach directly is itself the value in the importer model.

What is the most common mistake when launching one of these?

Building sync infrastructure before validating demand. Teams spend six weeks on a mirror, ranking and caching before learning whether anyone wants the product. Proxying the API directly gets a testable marketplace live in days, and the limitations that justify a database announce themselves clearly when they arrive.

  • marketplace
  • architecture
  • product
  • search
View as Markdown

One API, seven auction sources

Normalized search, source-aware detail, CDN image galleries, price history and archive access — all included on every plan.

Related reading