---
title: "Historical inventory"
description: "Ended listings moved into the archive, separate from ended rows still in the live table. Requires the archive scope. A last observed price is not a confirmed sale price."
canonical: "https://thecarapi.com/docs/archive"
contract_version: "2026-09-03"
api_base: "https://api.thecarapi.com"
source: "https://thecarapi.com/docs/archive.md"
---

# Historical inventory

Ended listings moved into the archive, separate from ended rows still in the live table. Requires the archive scope. A last observed price is not a confirmed sale price.

## GET /api/archive/search

Search ended auctions

**Scope:** `archive`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `site` | Query string | string | no | `openlane,ecarstrade` | Current API reference | Comma-separated source slugs from `/api/sites`, OR within the parameter. Case-insensitive; padding and empty members are ignored. An unknown slug is a `400` naming the offender.  |
| `site_exclude` | Query string | string | no | `copart` | Current API reference | Comma-separated source slugs to leave out. Same rules as `site`. |
| `brand` | Query string | string | no | `bmw` | Current API reference | Brand display name, slug (from `/api/brands`), or numeric `brand_id`. |
| `model` | Query string | string | no | `320d` | Current API reference | Model name or slug. |
| `country` | Query string | string | no | `DE` | Current API reference | ISO country code from `/api/countries`, or the pseudo-country `europe`. Accepted and ignored by `/api/sites` and `/load-models`.  |
| `fuel` | Query string | string | no | `Diesel` | Current API reference | Canonical fuel group from `/api/fuels`. |
| `gearbox` | Query string | string | no | `Automatic` | Current API reference | Canonical gearbox group from `/api/gearboxes`. |
| `year_from` | Query string | integer | no | `2018` | Current API reference | Lower bound on registration year, inclusive. |
| `year_to` | Query string | integer | no | `2024` | Current API reference | Upper bound on registration year, inclusive. |
| `production_year_from` | Query string | integer | no | `2018` | Current API reference | Lower bound on production year, inclusive. `production_year` falls back to the registration year where the source publishes no build year, so missing build-year evidence falls back to the registration-year dimension. |
| `production_year_to` | Query string | integer | no | `2024` | Current API reference | Upper bound on production year, inclusive. |
| `kilometers_from` | Query string | integer | no | `0` | Current API reference | Lower bound on mileage in kilometres. |
| `kilometers_to` | Query string | integer | no | `150000` | Current API reference | Upper bound on mileage in kilometres. |
| `price_from` | Query string | integer | no | `1000` | Current API reference | Lower bound on the public EUR price. |
| `price_to` | Query string | integer | no | `30000` | Current API reference | Upper bound on the public EUR price. |
| `archived_from` | Query string | string | no | `2026-07-01` | Current API reference | Only lots archived on or after this date (`YYYY-MM-DD`). Anything else is a `400`. |
| `archived_to` | Query string | string | no | `2026-08-31` | Current API reference | Only lots archived on or before this date (`YYYY-MM-DD`). Inclusive of the whole day named. |
| `vin` | Query string | string | no | `WBA8E9G50GNU12345` | Current API reference | Exact full-VIN filter. Punctuation and case are ignored. A value that is not a valid 17-character VIN is a `400`. VIN coverage varies; query /api/archive/stats before relying on it. |
| `sort` | Query string | string | no | `archived_desc` | Current API reference | Result ordering. |
| `limit` | Query string | integer | no | `20` | Current API reference | Page size. Capped at `pagination.max_limit` from `GET /api/contract` (100 by default); larger values are clamped down rather than rejected. Do not combine with `page_size` — that is a `400`.  |
| `offset` | Query string | integer | no | `0` | Current API reference | 0-based row offset. Do not combine with `page` — that is a `400`. Bounded by `pagination.max_offset` (5000 by default) on archive, catalog, top-offers and classifieds; /api/search and /api/listVehicles have no offset cap.  |
| `page` | Query string | integer | no | `1` | Current API reference | 1-based page number; maps to `offset = (page - 1) * limit`. Do not combine with `offset`. |
| `page_size` | Query string | integer | no | `20` | Current API reference | Alias for `limit`. Do not combine with `limit`. |
| `include_total` | Query string | boolean | no | `true` | Current API reference | `false` returns `total: null` and skips the count, which is faster. |

### Example requests

```http
GET https://api.thecarapi.com/api/archive/search?site=japan&year_from=2020&limit=20
```

```http
GET https://api.thecarapi.com/api/archive/search?brand=bmw&archived_from=2026-09-01
```

### Example response

```json
{
  "success": true,
  "results": [],
  "total": 0,
  "limit": 20,
  "offset": 0,
  "sort": "archived_desc",
  "page": 1,
  "page_size": 20,
  "total_pages": 0,
  "max_page": 0,
  "contract_version": "2026-09-03"
}
```

**Notes.** The historical counterpart to `/api/search`. It reads `auctions_archive`,
which holds lots that ended, stayed inactive for the retention window,
and were moved out of the live table with an `archived_at` stamp.
Nothing here is buyable.

**This is not a sold-price index.** `public_price_eur` is the last public price observed. `final_price` may be absent or have an unverified result basis; it is not proof of a completed sale. Call `/api/archive/stats` for the per-source
coverage before building anything on a particular field.

**No free-text `search` parameter.** The archive carries no trigram
index, and a substring scan across it costs seconds. `brand` and `model`
match exactly (case- and slug-insensitive), as they do on `/api/search`.

Default ordering is newest-archived first. The general offset cap
(`pagination.max_offset`, 5000 by default) applies — there is no
unfiltered deep-paging path here.


## GET /api/archive/auction/{site_slug}/{auction_id}

One archived auction in full

**Scope:** `archive`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `site_slug` | URL path | string | yes | `openlane` | Current API reference |  |
| `auction_id` | URL path | integer | yes | `38112900` | Current API reference | The source's auction id, as published on the search card. |

### Example requests

```http
GET https://api.thecarapi.com/api/archive/auction/encar/38112900
```

### Example response

```json
{
  "success": true,
  "auction": {
    "site_name": "encar",
    "auction_id": 38112900,
    "auction_id_str": "38112900",
    "archived": true,
    "archived_at": "2026-09-01T12:00:00",
    "final_price": null
  },
  "contract_version": "2026-09-03"
}
```

**Notes.** The archived counterpart to `/api/auction/{site_slug}/{auction_id}`, with
the same detail field set.

Two blocks are deliberately absent. There is no `live_price`: the lot is
over, so there is no bid to refresh. There is no `vault_gallery`: that is
served from the live gallery route. `thumbnail_url` and whatever the row
stored in `images` / `car_identification` are on the payload.

An archived row is never written again, so this response is cached for an
hour.


## GET /api/archive/stats

Archive coverage per source

**Scope:** `archive`

### Example requests

```http
GET https://api.thecarapi.com/api/archive/stats
```

### Example response

```json
{
  "success": true,
  "total": 0,
  "archived_from": null,
  "archived_to": null,
  "sources": [],
  "contract_version": "2026-09-03"
}
```

**Notes.** How much history exists, per source, and how much of it carries a price,
a reported final price, or a VIN. Read this before assuming a field is populated:
`with_final_price` is the number that stops the archive being mistaken
for a sold-price feed.

