---
title: "Vehicle images at scale: why hotlinking auction galleries fails"
description: "Auction listings carry 20–60 photographs each. Why source URLs expire, what hotlink protection does to your frontend, and what an image vault has to provide to be worth the storage."
slug: vehicle-image-cdn-api
canonical: https://thecarapi.com/blog/vehicle-image-cdn-api
category: Data engineering
author: TheCarApi Engineering
published: 2026-06-22
updated: 2026-08-07
tags: [images, CDN, WebP, performance]
---

# Vehicle images at scale: why hotlinking auction galleries fails

Images are the largest, most expensive and most fragile part of vehicle data — and the part teams discover late, usually in the form of a listings grid full of broken thumbnails.

A wholesale vehicle listing carries somewhere between twenty and sixty photographs. At a million live vehicles that is tens of millions of images — and unlike the specification fields, users actually look at these. A listing grid where a third of the thumbnails are broken reads as a broken product, regardless of how good the underlying data is.

The naive approach is to store the source image URL alongside the listing and let the browser fetch it. It works in development. Here is why it does not survive.

## Four reasons hotlinking fails

### 1. Source URLs expire

This is the fatal one. Auction platforms commonly stop serving media for lots that have closed — sometimes within days, sometimes after weeks, and rarely with any announcement. Live listings look fine. Your historical archive rots quietly from the oldest end, and by the time anyone notices, months of galleries are gone with no way to recover them.

### 2. Hotlink protection

Many sources check the `Referer` header or require a valid session cookie. The failure mode is genuinely nasty: images load for you (you visited the source recently), fail for your users, and behave differently across browsers depending on referrer policy. It presents as an intermittent bug and is frequently misdiagnosed for weeks.

### 3. File sizes built for a different use case

Source galleries are full-resolution JPEGs, commonly 2–6 MB each. Loading a twenty-four-card grid with one thumbnail each means fetching perhaps 60 MB to render a page that needs about 400 KB of imagery. On mobile that is not slow, it is unusable.

### 4. You have no control over availability

Your product's perceived performance becomes a function of seven third-party CDNs you have no relationship with, no SLA against, and no cache control over. One source having a slow morning becomes your incident.

> **The failure is silent and delayed** — Every one of these problems is invisible during development and for the first few weeks in production. They surface together, later, as "the site looks broken" — which is why image strategy belongs in the initial architecture rather than in a follow-up ticket.

## What an image vault has to do

Copying images is the easy part. These are the properties that determine whether the copy is actually worth its storage cost:

1. **Copy at ingest, not on demand.** Lazy copying means the first user to view an old lot triggers a fetch against a URL that may already be dead. Copy when the listing is first seen, while the source still serves it.
2. **Re-encode.** WebP at sensible quality typically cuts payload substantially against source JPEG with no visible difference in a listing grid.
3. **Serve multiple sizes.** A thumbnail grid and a full-screen gallery have completely different requirements, and serving one image for both wastes bandwidth in one direction or detail in the other.
4. **Stable URLs that outlive the lot.** The entire point. If the served URL breaks when the auction closes, you have built an expensive cache rather than an archive.
5. **Preserve ordering and role.** Which image is primary, which section of the vehicle each belongs to, exterior versus interior versus damage detail. Galleries presented in arbitrary order are noticeably worse to use.
6. **Record dimensions.** Without width and height in the payload, every image causes layout shift on load, which is both a user-experience problem and a Core Web Vitals penalty.

```bash
curl -s "https://api.thecarapi.com/api/auction-images/encar/38112900" \
  -H "X-API-Key: $API_KEY"
```

_Galleries are addressed by the same `site/auction_id` pair as detail and price history, and return `served_url` alongside ordering, section and dimensions._

## Consuming galleries efficiently

Two patterns that account for most of the practical difference in page performance.

### Do not fetch galleries in search

Search results need one thumbnail per card. Full gallery payloads for twenty-four results is a large response containing data for images the user will almost certainly never open. Use the thumbnail on the search card and fetch the gallery only when a detail view opens.

```javascript
// Search card — thumbnail only, from the search response
<img
  src={listing.thumbnail_url}
  alt={`${listing.registration_year} ${listing.clean_make} ${listing.clean_model}`}
  width={400}
  height={300}
  loading="lazy"
/>

// Detail view — gallery fetched on open, first image eager
const images = await fetch(
  `${API}/api/auction-images/${site}/${id}`,
  { headers: { 'X-API-Key': key } }
).then(r => r.json());
```

### Write real alt text

Vehicle imagery has an unusual advantage here: you have structured data describing exactly what is in the picture. `alt="2021 Kia Niro, exterior front three-quarter"` costs nothing to generate, is genuinely useful to screen reader users, and is one of the few places where accessibility and image SEO point in exactly the same direction. Empty alt attributes on a page whose entire content is vehicles is a wasted signal.

> **Dimensions prevent layout shift** — If the API returns width and height, set them on the element. Reserved space means the grid does not jump as images arrive — the single cheapest improvement available to an image-heavy listing page, and it is measured directly by Cumulative Layout Shift.

## The storage maths

Worth doing explicitly, because the intuition is usually wrong in both directions.

|  | Source JPEG | WebP, re-encoded |
| --- | --- | --- |
| Average image | ~2.5 MB | ~150 KB |
| One listing (30 images) | ~75 MB | ~4.5 MB |
| 1M live listings | **~75 TB** | **~4.5 TB** |

_Indicative figures — actual ratios depend on source quality and target encoding settings._

Storage at a few terabytes is inexpensive. The costs that actually hurt are elsewhere: the residential-proxy bandwidth to fetch the originals in the first place, and the CDN egress to serve them afterwards — which scales with your traffic rather than your catalogue, and is therefore the bill that grows exactly when things are going well. [The scraping cost breakdown](/blog/scraping-car-auction-sites-vs-api) puts both lines in context.

## Rights, briefly

Listing photographs are copyrighted works, and the position on re-hosting them is genuinely distinct from the position on extracting factual specifications. This is not legal advice and the answer varies by jurisdiction and by the terms you are operating under — but it is a real consideration, and it is one of the substantive differences between collecting images yourself and consuming them from a provider who has a commercial relationship with the sources.

For the fuller picture on what auction data contains and how to consume it, start with [the auction data guide](/blog/car-auction-api-guide), or see [the image endpoints in the reference](/docs/auctions).

## Frequently asked questions

### Why do auction listing images break after a few weeks?

Source platforms commonly stop serving media for lots that have closed, often within days or weeks of the auction ending. Live listings continue to work, so the problem is invisible at first and shows up as historical galleries decaying from the oldest end — with no way to recover images you did not copy while the source was still serving them.

### Can I just link directly to source auction images?

Only if you never need to show a listing after it closes. Direct linking also runs into hotlink protection that checks the request referrer — which causes intermittent failures that look like a browser bug — and serves multi-megabyte originals to mobile users. For anything with a historical view, images have to be copied at ingest.

### How much storage do vehicle images actually need?

Roughly 4–5 TB for a million listings at thirty images each once re-encoded to WebP, against roughly 75 TB for the source JPEGs. Storage itself is cheap; the expensive lines are the bandwidth to fetch the originals over residential proxies and the CDN egress to serve them, the latter scaling with your traffic rather than your catalogue size.

### What should vehicle image alt text say?

Describe the vehicle and the view: "2021 Kia Niro, exterior front three-quarter". You already hold structured data for make, model and year, so this can be generated automatically. It is one of the few cases where the accessibility requirement and the image SEO opportunity are satisfied by exactly the same text.

### Should search results include full image galleries?

No. Search cards need one thumbnail each; returning thirty image records per result multiplies the response size for data the user will almost certainly never open. Use the thumbnail in the search payload and fetch the gallery on demand when a detail view opens.
