# Catalogue

Browse the AutoUncle vehicle catalogue and get the IDs that pin a vehicle exactly. All catalogue endpoints are free, need the `catalogue:read` scope and share a per-minute rate limit (default 120 requests per minute per workspace). Field tables are generated from the response schemas in the [OpenAPI contract](/openapi.yaml), which also validate every response in the test suite.

The usual path is brand → model → generation → drivetrain. [Build a catalogue picker](/docs/guides/catalogue-picker) walks through it, and [vehicle catalogue](/docs/catalogue) explains IDs, versions and caching.

Catalogue IDs are opaque strings such as `b-0957579dc5bca6de229d2f32` (brand) or `dv-947a3199394a5a4b41cb2869` (drivetrain). Store them as returned; do not parse or construct them. Lists are sorted by name and are not paginated.

## GET /v1/catalogue/search

Search makes and models.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `q` | query | string | Yes | Two to 200 characters. Case-insensitive substring match against brand names and "brand model" names as the catalogue spells them (for example VW, not Volkswagen). Returns up to 20 brands and 80 models. 2 to 200 characters. |

### Response

`application/json`, a `CatalogueSearchResults`: Makes and models matching the search text: up to 20 brands, then up to 80 models. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | Matching brands first, then matching models. Not paginated. At most 100 items. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueSearchResult`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Brand or model ID. |
| `name` | string | Brand name, or model name without the brand (for example `Golf Alltrack`). |
| `object` | string | `brand` or `model`. One of `brand`, `model`. |
| `brand_id` | string | Parent brand ID. Models only. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`invalid_request`](/docs/errors#invalid_request) | 400 | No | Send a request matching the documented schema. |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl 'https://data-services.autouncle.com/v1/catalogue/search?q=golf' \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/search?q=golf")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/search?q=golf",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/search?q=golf", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/brands

List vehicle makes.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Response

`application/json`, a `CatalogueBrandList`: Vehicle makes. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | The items, sorted by name. Not paginated. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueBrand`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Brand ID, for example `b-0957579dc5bca6de229d2f32`. Opaque: store it as returned. |
| `name` | string | Catalogue brand name, for example `VW`. |
| `object` | string | Always `brand`. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/brands \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/brands")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/brands",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/brands", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/brands/{id}/models

List models for a make.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Identifier from a previous response. At most 200 characters. |

### Response

`application/json`, a `CatalogueModelList`: Models of one make. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | The items, sorted by name. Not paginated. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueModel`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Model ID, for example `cm-6bb52590daf6d1b19108ec93`. |
| `name` | string | Model name without the brand, for example `Golf`. |
| `object` | string | Always `model`. |
| `brand_id` | string | Parent brand ID. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`unknown_catalogue_id`](/docs/errors#unknown_catalogue_id) | 404 | No | The catalogue ID is unknown. Fetch current IDs from the catalogue API. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/models \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/models")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/models",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/models", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/models/{id}/generations

List generations for a model.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Model ID from the models or search endpoint. A model alias returns the generations it stands for. At most 200 characters. |
| `year` | query | integer | No | Registration or model year. Returns only generations whose production years include it. Must be an integer from 1900 to next year. |

### Response

`application/json`, a `CatalogueGenerationList`: Generations of one model, optionally narrowed by year. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | The items, sorted by name. Not paginated. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueGeneration`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Generation ID, for example `mg-40c5d8de40bb48ae60fc0a6c`. |
| `name` | string | Generation name, including body variant where relevant, for example `Golf VIII Variant`. |
| `object` | string | Always `generation`. |
| `model_id` | string | Parent model ID. |
| `from_year` | integer | First production year. Omitted when unknown. |
| `to_year` | integer | Last production year. Omitted when unknown or still in production. |
| `body` | string | Catalogue body type. Omitted when unknown. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`invalid_request`](/docs/errors#invalid_request) | 400 | No | Send a request matching the documented schema. |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`unknown_catalogue_id`](/docs/errors#unknown_catalogue_id) | 404 | No | The catalogue ID is unknown. Fetch current IDs from the catalogue API. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl 'https://data-services.autouncle.com/v1/catalogue/models/cm-6bb52590daf6d1b19108ec93/generations?year=2021' \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/models/cm-6bb52590daf6d1b19108ec93/generations?year=2021")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/models/cm-6bb52590daf6d1b19108ec93/generations?year=2021",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/models/cm-6bb52590daf6d1b19108ec93/generations?year=2021", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/generations/{id}/drivetrains

List engine and transmission variants.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Generation ID from the generations endpoint. At most 200 characters. |
| `fuel` | query | string | No | Keep drivetrains with this fuel. Accepts the public fuel values from /v1/catalogue/enums, such as petrol or diesel. At most 200 characters. |
| `transmission` | query | string | No | Keep drivetrains with this transmission, manual or automatic. Case-insensitive. At most 200 characters. |
| `power_hp` | query | string | No | Keep drivetrains with exactly this power in horsepower. At most 200 characters. |
| `model_id` | query | string | No | Optional selected model UUID. Restricts drivetrain results to that model alias, such as GLC300e. |

### Response

`application/json`, a `CatalogueDrivetrainList`: Drivetrains of one generation, optionally filtered. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | The items, sorted by name. Not paginated. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueDrivetrain`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Drivetrain ID, for example `dv-947a3199394a5a4b41cb2869`. |
| `name` | string | Engine and transmission designation, for example `1.5 TSI (130 Hp)`. |
| `object` | string | Always `drivetrain`. |
| `generation_id` | string | Parent generation ID. |
| `fuel` | string | Fuel. Usually a public fuel value such as `petrol`, `diesel` or `plug_in_hybrid_petrol`; some catalogue values, such as `CNG_Hybrid`, are passed through unchanged. Omitted when unknown. |
| `power_hp` | number | Power in horsepower. Omitted when unknown. |
| `transmission` | string | Lowercase catalogue transmission, usually `manual` or `automatic`. Omitted when unknown. |
| `engine_size_l` | number | Engine displacement in litres. Omitted when unknown. |
| `battery_kwh` | number | Battery capacity in kWh for electrified drivetrains. Omitted when unknown. |
| `drive` | string | Catalogue traction label, for example `2WD` or `AWD`. Note that this is not the `fwd`/`rwd`/`awd`/`4wd` value used in `vehicle.drive`. Omitted when unknown. |
| `doors` | integer | Number of doors. Omitted when unknown. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`unknown_catalogue_id`](/docs/errors#unknown_catalogue_id) | 404 | No | The catalogue ID is unknown. Fetch current IDs from the catalogue API. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl 'https://data-services.autouncle.com/v1/catalogue/generations/mg-40c5d8de40bb48ae60fc0a6c/drivetrains?fuel=petrol&transmission=manual' \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/generations/mg-40c5d8de40bb48ae60fc0a6c/drivetrains?fuel=petrol&transmission=manual")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/generations/mg-40c5d8de40bb48ae60fc0a6c/drivetrains?fuel=petrol&transmission=manual",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/generations/mg-40c5d8de40bb48ae60fc0a6c/drivetrains?fuel=petrol&transmission=manual", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/brands/{id}/equipment-variants

List equipment variants.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Brand ID from the brands or search endpoint. At most 200 characters. |

### Response

`application/json`, a `CatalogueEquipmentVariantList`: Equipment variants of one make. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `data` | object array | The items, sorted by name. Not paginated. |
| `notes` | [Note](/docs/notices#notes) array | Notes for this result. Usually empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | The catalogue attribution, pointing at `/data`, when the list contains catalogue data. |

Each item in `data`, a `CatalogueEquipmentVariant`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Equipment variant ID, for example `ev-227a3875b490f1310578b286`. |
| `name` | string | Trim or equipment line name, for example `Active`. |
| `object` | string | Always `equipment_variant`. |
| `brand_id` | string | Parent brand ID. Omitted when the catalogue has no brand for it. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`unknown_catalogue_id`](/docs/errors#unknown_catalogue_id) | 404 | No | The catalogue ID is unknown. Fetch current IDs from the catalogue API. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/equipment-variants \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/equipment-variants")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/equipment-variants",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/brands/b-0957579dc5bca6de229d2f32/equipment-variants", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/{kind}/{id}

Get an item by catalogue UUID.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `kind` | path | string | Yes | One of brands, models, generations, drivetrains or equipment-variants. Any other value returns not_found. At most 200 characters. |
| `id` | path | string | Yes | The catalogue ID of an item of that kind. At most 200 characters. |

### Response

`application/json`, a `CatalogueItem`: One catalogue item with the same fields as in its list endpoint, plus notes and attributions. `object` tells which kind it is. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| `object` | Fields |
| --- | --- |
| `brand` | The fields of an item in [GET /v1/catalogue/brands](/docs/reference/catalogue#get-v1-catalogue-brands), plus `notes` and `attributions`. |
| `model` | The fields of an item in [GET /v1/catalogue/brands/{id}/models](/docs/reference/catalogue#get-v1-catalogue-brands-id-models), plus `notes` and `attributions`. |
| `generation` | The fields of an item in [GET /v1/catalogue/models/{id}/generations](/docs/reference/catalogue#get-v1-catalogue-models-id-generations), plus `notes` and `attributions`. |
| `drivetrain` | The fields of an item in [GET /v1/catalogue/generations/{id}/drivetrains](/docs/reference/catalogue#get-v1-catalogue-generations-id-drivetrains), plus `notes` and `attributions`. |
| `equipment_variant` | The fields of an item in [GET /v1/catalogue/brands/{id}/equipment-variants](/docs/reference/catalogue#get-v1-catalogue-brands-id-equipment-variants), plus `notes` and `attributions`. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`not_found`](/docs/errors#not_found) | 404 | No | The requested resource was not found. |
| [`unknown_catalogue_id`](/docs/errors#unknown_catalogue_id) | 404 | No | The catalogue ID is unknown. Fetch current IDs from the catalogue API. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/drivetrains/dv-947a3199394a5a4b41cb2869 \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/drivetrains/dv-947a3199394a5a4b41cb2869")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/drivetrains/dv-947a3199394a5a4b41cb2869",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/drivetrains/dv-947a3199394a5a4b41cb2869", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/enums

List supported input values.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Response

`application/json`, a `CatalogueEnums`: The values accepted by enumerated request fields. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `enums`. |
| `data` | object | Accepted values per request field. |
| `data.fuel` **required** | array | Public fuel values accepted in `vehicle.fuel`. |
| `data.transmission` **required** | array | Values accepted in `vehicle.transmission`: `manual`, `automatic`. |
| `data.drive` **required** | array | Values accepted in `vehicle.drive`: `fwd`, `rwd`, `awd`, `4wd`. |
| `data.mileage_units` **required** | array | Values accepted in `vehicle.mileage.unit`: `km`, `mi`, `mil`. |
| `data.price_basis` **required** | array | Values accepted in `pricing.price_basis`: `dealer_retail`, `private_sale`. |
| `data.resolution` **required** | array | Values accepted in `options.resolution`: `auto`, `no_ai`, `strict`. |
| `data.precision` **required** | array | Precision grades, best first, accepted in `options.min_precision`: `high`, `medium`, `low`, `indicative`. |
| `data.equipment` **required** | array | Equipment feature keys accepted in `vehicle.equipment` and returned in a Vehicle's `equipment`, such as `EXTERIOR_TOWBAR_FIXED` or `BATTERY_HEAT_PUMP`. |
| `notes` | [Note](/docs/notices#notes) array | Always empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | Always empty. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/enums \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/enums")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/enums",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/enums", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/countries

List supported markets and mileage units.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Response

`application/json`, a `CatalogueCountries`: Every market the service can value, and whether new workspaces can value it. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | Always `list`. |
| `data` | array | One entry per market. |
| `data[].id` **required** | string | Market code to send as `country`, an ISO 3166-1 alpha-2 code such as `DK` or `GB`. Pattern `^[A-Z]{2}$`. |
| `data[].mileage_unit` **required** | string | The market's mileage unit. One of `km`, `mi`, `mil`. |
| `data[].availability` **required** | string | `general`: enabled for every new workspace. `on_request`: listed for completeness, but a workspace can value it only after AutoUncle enables it; until then a valuation returns 403 country_not_enabled. GET /v1/account shows what your workspace may value. One of `general`, `on_request`. |
| `notes` | [Note](/docs/notices#notes) array | Always empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | Always empty. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/countries \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/countries")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/countries",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/countries", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```

## GET /v1/catalogue/version

Get the catalogue version.

- **Scope:** `catalogue:read`
- **Cost:** Free.
- **Rate limit:** catalogue bucket, default 120 requests per minute. See [limits](/docs/concepts/limits).

### Response

`application/json`, a `CatalogueVersion`: The current catalogue version. Errors return a [Problem](/docs/reference/valuations#the-problem-object) as `application/problem+json`.

| Field | Type | Description |
| --- | --- | --- |
| `version` | string | Catalogue version, for example `5.6.7:NEW`. Refresh cached catalogue data when it changes. |
| `notes` | [Note](/docs/notices#notes) array | Always empty. |
| `attributions` | [Attribution](/docs/notices#attributions) array | Always empty. |

### Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID. |

### Errors

| Code | HTTP | Retryable | Meaning |
| --- | --- | --- | --- |
| [`unauthenticated`](/docs/errors#unauthenticated) | 401 | No | Supply an API key as a Bearer token. |
| [`invalid_api_key`](/docs/errors#invalid_api_key) | 401 | No | Supply a valid AutoUncle Data Services API key. |
| [`key_revoked`](/docs/errors#key_revoked) | 401 | No | This key has expired or been revoked. Create a new key. |
| [`insufficient_scope`](/docs/errors#insufficient_scope) | 403 | No | Use a key with the required scope. |
| [`organization_pending`](/docs/errors#organization_pending) | 403 | No | This workspace is waiting for AutoUncle to approve it. |
| [`organization_suspended`](/docs/errors#organization_suspended) | 403 | No | This organization is inactive. Contact support. |
| [`rate_limited`](/docs/errors#rate_limited) | 429 | Yes | The request rate limit was reached. Retry after the current minute. |

### Examples

**curl**

```bash
curl https://data-services.autouncle.com/v1/catalogue/version \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY"
```

**Ruby**

```ruby
require "json"
require "net/http"

uri = URI("https://data-services.autouncle.com/v1/catalogue/version")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
```

**Python**

```python
import json
import os

import requests

response = requests.get(
    "https://data-services.autouncle.com/v1/catalogue/version",
    headers={
        "Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))
```

**JavaScript**

```javascript
const response = await fetch("https://data-services.autouncle.com/v1/catalogue/version", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
  },
});
console.log(JSON.stringify(await response.json(), null, 2));
```
