---
title: "Filter facets"
description: "Discover live filter values and counts. Facet responses cache for about 600 seconds. A filter sidebar can read every flat dimension in one call with /api/facets."
canonical: "https://thecarapi.com/docs/facets"
contract_version: "2026-08-19"
api_base: "https://api.thecarapi.com"
source: "https://thecarapi.com/docs/facets.md"
---

# Filter facets

Discover live filter values and counts. Facet responses cache for about 600 seconds. A filter sidebar can read every flat dimension in one call with /api/facets.

## GET /api/facets

Every flat facet dimension in one request instead of six.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `fields` | Query string | string | no | `brands,fuels,gearboxes` | The dimensions your sidebar actually renders. | Comma-separated subset of brands, years, fuels, countries, gearboxes, sites. Defaults to all of them. models is not available here — it is brand-scoped and stays at /api/models. |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/api/facets?fields=brands,fuels,gearboxes&country=DE
```

```http
GET https://api.thecarapi.com/api/facets?fields=brands,years,sites&damaged=true
```

### Example response

```json
{
  "success": true,
  "brands": [
    {
      "id": 12,
      "name": "BMW",
      "slug": "bmw",
      "count": 3266
    }
  ],
  "fuels": [
    "Diesel",
    "Petrol"
  ],
  "gearboxes": [
    "Automatic",
    "Manual"
  ]
}
```

### Response fields

| Field | Type | Meaning |
| --- | --- | --- |
| `brands / years / fuels / countries / gearboxes / sites` | array | Each field is its own endpoint’s payload merged verbatim — countries still ships country_details alongside it, and no field gains or loses counts by being requested here. |
| `errors` | object | Present only when a dimension could not be served: { field: reason }. Every other field is still returned, so one slow dimension cannot blank a filter sidebar. |

**Notes.** Every filter accepted by the individual facet endpoints applies here, per field, exactly as its own endpoint would apply it. The per-dimension endpoints below are unchanged and stay fully supported — this is an additional way to read the same data. Scope search, the same scope that already grants them, and the fan-out bills one quota unit rather than six.

## GET /api/brands

List brands with round-trippable slugs and live inventory counts.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |
| `search` | Query string | string | no | `bm` | Free text entered by your user. | Substring filter on brand name. |
| `ordering` | Query string | enum | no | `-count` | Choose name, -name, count, or -count. | name, -name, count, or -count. |
| `limit` | Query string | integer | no | `20` | Result count chosen by your application. | Maximum number of values. |

### Example requests

```http
GET https://api.thecarapi.com/api/brands?search=bm&ordering=-count&limit=20
```

```http
GET https://api.thecarapi.com/api/brands?country=DE&damaged=true
```

### Example response

```json
{
  "success": true,
  "brands": [
    {
      "id": 12,
      "name": "BMW",
      "slug": "bmw",
      "count": 1543
    }
  ]
}
```

## GET /api/models

List models for one brand with live inventory counts.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `brand` | Query string | string \| integer | yes | `bmw` | /api/brands -> brands[].slug (or id/name) | Brand name, slug, or brand_id. |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |
| `search` | Query string | string | no | `x` | Free text entered by your user. | Substring filter on model name. |
| `ordering` | Query string | enum | no | `-count` | Choose name, -name, count, or -count. | name, -name, count, or -count. |

### Example requests

```http
GET https://api.thecarapi.com/api/models?brand=bmw&ordering=-count
```

```http
GET https://api.thecarapi.com/api/models?brand=12&search=x&country=DE
```

### Example response

```json
{
  "success": true,
  "models": [
    {
      "name": "320d",
      "slug": "320d",
      "count": 210
    }
  ]
}
```

## GET /api/years

List registration years available in current inventory.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/api/years?country=DE
```

```http
GET https://api.thecarapi.com/api/years?damaged=true&buy_now=true
```

### Example response

```json
{
  "success": true,
  "years": [
    2024,
    2023,
    2022,
    2021
  ]
}
```

## GET /api/fuels

List canonical fuel groups available in current inventory.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/api/fuels?country=DE
```

```http
GET https://api.thecarapi.com/api/fuels?buy_now=true
```

### Example response

```json
{
  "success": true,
  "fuels": [
    "Diesel",
    "Electric",
    "Hybrid",
    "Mild Hybrid",
    "Petrol",
    "Plug-in Hybrid"
  ]
}
```

**Notes.** Six groups, and the three hybrid kinds are distinct: Hybrid (full hybrid), Mild Hybrid (48V assist, cannot drive on the motor alone) and Plug-in Hybrid. The fuel filter matches a group whole, so fuel=Hybrid returns full hybrids only. To catch every electrified car, send all three.

## GET /api/gearboxes

List canonical gearbox groups available in current inventory.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/api/gearboxes?country=KR
```

```http
GET https://api.thecarapi.com/api/gearboxes?damaged=true
```

### Example response

```json
{
  "success": true,
  "gearboxes": [
    "Automatic",
    "Manual"
  ]
}
```

## GET /api/countries

List vehicle-location countries and display names.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/api/countries?buy_now=true
```

```http
GET https://api.thecarapi.com/api/countries?damaged=true
```

### Example response

```json
{
  "success": true,
  "countries": [
    "DE",
    "JP",
    "KR",
    "NL"
  ],
  "country_details": [
    {
      "code": "DE",
      "name": "Germany"
    },
    {
      "code": "JP",
      "name": "Japan"
    },
    {
      "code": "KR",
      "name": "South Korea"
    }
  ]
}
```

**Notes.** country=europe means "every origin that is not overseas" and is implemented as an exclusion, not a list: it currently excludes KR (Encar) and JP (the Japanese auction houses), and rows with no recorded country are treated as European and included. If you need strict membership, pass explicit ISO codes instead.

## GET /api/sites

List auction source slugs with live inventory counts.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict counts to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict counts to Buy-Now inventory. |

### Example requests

```http
GET https://api.thecarapi.com/api/sites?buy_now=true
```

```http
GET https://api.thecarapi.com/api/sites?damaged=true
```

### Example response

```json
{
  "success": true,
  "sites": [
    {
      "id": 1,
      "name": "encar",
      "count": 9021
    },
    {
      "id": 2,
      "name": "openlane",
      "count": 4110
    },
    {
      "id": 3,
      "name": "ecarstrade",
      "count": 3187
    },
    {
      "id": 4,
      "name": "japanauction",
      "count": 1642
    }
  ]
}
```

**Notes.** This is the discovery endpoint for both /api/search?site= and /api/auction/{site}/{id}. Counts here respect every other filter on the request but ignore site / site_exclude themselves — a facet that filtered by its own dimension could only ever return the sources you already named. The European classifieds network is retail data, not auction inventory, so it never appears here; it has its own endpoint group.

## GET /load-models

Return the complete model catalog grouped by brand.

**Scope:** `search`

### Parameters

| Parameter | Send in | Type | Required | Example | Where the value comes from | Description |
| --- | --- | --- | --- | --- | --- | --- |
| `damaged` | Query string | boolean | no | `true` | Your filter choice. | Restrict to damaged or broken vehicles. |
| `buy_now` | Query string | boolean | no | `true` | Your filter choice. | Restrict to Buy-Now inventory. |
| `country` | Query string | string | no | `DE` | /api/countries -> country_details[].code | ISO country code or europe. |
| `steering` | Query string | enum | no | `left` | left \| lhd \| right \| rhd — any other value is a 400. | Restrict to left- or right-hand-drive vehicles. Slower than an unfiltered facet call, because it is computed live rather than read from the precomputed facet table. |

### Example requests

```http
GET https://api.thecarapi.com/load-models?country=DE
```

```http
GET https://api.thecarapi.com/load-models?buy_now=true&damaged=false
```

### Example response

```json
{
  "BMW": [
    {
      "text": "320d"
    },
    {
      "text": "X5"
    }
  ],
  "Volvo": [
    {
      "text": "XC60"
    }
  ]
}
```

**Notes.** This response is shaped differently from every other endpoint in the API: the body IS the map. Every key is a brand name and every value is that brand list of models — there is no wrapper object, no success flag and no contract metadata, because the keys are data and nothing else may share that namespace. Read the correlation id from the X-Request-ID header instead. An error response IS wrapped and does carry success: false, so test for the error shape rather than for a success flag that never appears. If you write a generic client wrapper that asserts body.success, special-case this one route. Model entries are objects, not bare strings, and each list is sorted by name. Heavy — cache it, and prefer /api/models for interactive brand-specific dropdowns.
