# API overview

The REST API is a small JSON API over HTTPS. This page covers the conventions every endpoint shares; the endpoint pages list each field, example and error. The [OpenAPI 3.1 contract](/openapi.yaml) ([JSON](/openapi.json)) is the canonical, machine-readable description, and the field tables in this reference are generated from it.

## Endpoints

| Method and path | Service | Purpose | Scope | Cost |
| --- | --- | --- | --- | --- |
| [`POST /v1/valuations`](/docs/reference/valuations#post-v1-valuations) | Valuation | Resolve and value a vehicle | `valuations:write` | One credit for a successful (`valued`) live valuation, plus one when requested comparables are returned, one when a requested trade-in price is returned and one when sent photos were used. The similar-cars link is free. Test-key valuations, refusals and failures are free. |
| [`GET /v1/valuations/{id}`](/docs/reference/valuations#get-v1-valuations-id) | Valuation | Retrieve your workspace’s recorded valuation | `valuations:read` | Free. Counts towards the per-minute valuation rate limit. |
| [`POST /v1/market`](/docs/reference/market#post-v1-market) | Market & demand | Market and demand figures for a car type | `valuations:write` | One credit for a `measured` live result. `partial` and `insufficient_data` results, test keys, refusals, failures and idempotent replays are free. |
| [`POST /v1/selling-times`](/docs/reference/valuations#post-v1-selling-times) | Market & demand | Value a vehicle and forecast its selling time | `valuations:write` | Two credits for a successful (`valued`) live forecast: one for the valuation and one for the forecast, plus one when requested comparables are returned. Test keys, refusals and failures, including a forecast that could not be made, are free. |
| [`POST /v1/vehicles/normalize`](/docs/reference/vehicles#post-v1-vehicles-normalize) | Vehicle identification | Resolve a vehicle without valuing it | `vehicles:read` | One credit for a successful (`normalized`) live normalization, plus one when sent photos were used. Test keys, refusals, failures and idempotent replays are free. |
| [`POST /v1/vehicles/decode`](/docs/reference/vehicles#post-v1-vehicles-decode) | Vehicle identification | Decode a VIN into an AutoUncle vehicle | `vehicles:read` | One credit for a live lookup that returns vehicle data (`resolved`, `suggested` or `ambiguous`). `no_match`, failures and test keys are free. |
| [`POST /v1/vehicles/hsn-tsn`](/docs/reference/vehicles#post-v1-vehicles-hsn-tsn) | Vehicle identification | Look up German HSN/TSN type codes | `vehicles:read` | One credit for a live lookup that returns vehicle data (`resolved`, `suggested` or `ambiguous`). `no_match`, failures and test keys are free. |
| [`POST /v1/vehicles/lookup`](/docs/reference/vehicles#post-v1-vehicles-lookup) | Licence-plate lookup | Look up a vehicle by registration plate | `vehicles:read` | One credit for a live lookup that finds the vehicle. `no_match`, failures, unsupported countries and test keys are free. |
| [`GET /v1/catalogue/search`](/docs/reference/catalogue#get-v1-catalogue-search) | Vehicle catalogue | Search makes and models | `catalogue:read` | Free. |
| [`GET /v1/catalogue/brands`](/docs/reference/catalogue#get-v1-catalogue-brands) | Vehicle catalogue | List vehicle makes | `catalogue:read` | Free. |
| [`GET /v1/catalogue/brands/{id}/models`](/docs/reference/catalogue#get-v1-catalogue-brands-id-models) | Vehicle catalogue | List models for a make | `catalogue:read` | Free. |
| [`GET /v1/catalogue/models/{id}/generations`](/docs/reference/catalogue#get-v1-catalogue-models-id-generations) | Vehicle catalogue | List generations for a model | `catalogue:read` | Free. |
| [`GET /v1/catalogue/generations/{id}/drivetrains`](/docs/reference/catalogue#get-v1-catalogue-generations-id-drivetrains) | Vehicle catalogue | List engine and transmission variants | `catalogue:read` | Free. |
| [`GET /v1/catalogue/brands/{id}/equipment-variants`](/docs/reference/catalogue#get-v1-catalogue-brands-id-equipment-variants) | Vehicle catalogue | List equipment variants | `catalogue:read` | Free. |
| [`GET /v1/catalogue/{kind}/{id}`](/docs/reference/catalogue#get-v1-catalogue-kind-id) | Vehicle catalogue | Get an item by catalogue UUID | `catalogue:read` | Free. |
| [`GET /v1/catalogue/enums`](/docs/reference/catalogue#get-v1-catalogue-enums) | Vehicle catalogue | List supported input values | `catalogue:read` | Free. |
| [`GET /v1/catalogue/countries`](/docs/reference/catalogue#get-v1-catalogue-countries) | Vehicle catalogue | List supported markets and mileage units | `catalogue:read` | Free. |
| [`GET /v1/catalogue/version`](/docs/reference/catalogue#get-v1-catalogue-version) | Vehicle catalogue | Get the catalogue version | `catalogue:read` | Free. |
| [`GET /v1/account`](/docs/reference/account#get-v1-account) | Account | Inspect key permissions and available credits | `account:read` | Free. Counts towards the per-minute valuation rate limit. |

The same operations are available to agents as MCP tools; see the [tool reference](/docs/mcp/tools). [APIs at a glance](/docs/apis) groups them by service.

## Base URL

```text
https://data-services.autouncle.com
```

All endpoints are under `/v1`. Use HTTPS; there is no separate sandbox host. A test key (`au_test_…`) gives you simulated results on the same URL.

## Authentication

Send your API key as a Bearer token on every request:

```http
Authorization: Bearer au_test_...
```

`X-Api-Key: au_test_...` is also accepted, but prefer `Authorization`. Keys belong to a workspace, are either test or live, and carry scopes. See [authentication & keys](/docs/authentication).

## Requests

- **JSON bodies.** `POST /v1/valuations` requires `Content-Type: application/json` and a JSON object of at most 1 MB. Any other content type returns `400 invalid_request`.
- **Strict schemas.** Unknown fields are rejected with `400 invalid_request`, and each problem is listed in `errors[]` with a JSON Pointer to the field. This catches typos such as `milage` before they cost you precision.
- **Omit unknowns.** Leave out what you do not know rather than sending empty strings, zeros or guesses. Absent values are reflected in precision and improvement hints.
- **Query parameters** are plain strings. Encode spaces as `%20`.
- **Country codes** are ISO 3166-1 alpha-2 and case-insensitive (`DK` or `dk`). See [markets](/docs/concepts/markets).

## Request headers

| Header | Required | Purpose |
| --- | --- | --- |
| `Authorization` | Yes | `Bearer <API key>`. |
| `Content-Type` | For POST | `application/json`. |
| `Idempotency-Key` | Recommended for POST | A unique key per intended valuation, 1 to 200 printable ASCII characters. See [idempotency](/docs/concepts/idempotency). |

## Responses

- **JSON.** Successful responses are `application/json`. Every result has a `notes` array and an `attributions` array, even when they are empty. See [notes and data sources](/docs/notices).
- **Vehicles.** Every result that describes a vehicle returns it as `vehicle`, an [AutoUncle Vehicle Schema (AVS)](https://github.com/AutoUncle/avs) 0.3 vehicle document, with how it was identified beside it in `identification`. Unknown values are left out, never `null`. Post the `vehicle` back unchanged as a later request's `vehicle`. See [the Vehicle object](/docs/reference/vehicles#the-vehicle-object).
- **Errors** before a valuation is recorded are `application/problem+json` [Problem documents](/docs/reference/valuations#the-problem-object) with a stable `code`.
- **Recorded outcomes.** A valuation that is refused or fails is recorded and returned as the normal valuation envelope with `status` and a nested `error`, using the error's HTTP status (for example `422` or `504`).
- **New fields may appear.** Ignore fields you do not know; they are added without a new version. Do not rely on field order.

## Response headers

| Header | When | Meaning |
| --- | --- | --- |
| `RateLimit-Limit` | Rate-limited endpoints | Requests allowed in the current one-minute window. |
| `RateLimit-Remaining` | Rate-limited endpoints | Requests left in the window. |
| `RateLimit-Reset` | Rate-limited endpoints | Seconds until the window resets. |
| `Retry-After` | `429` and capacity `503` | Seconds to wait before retrying. The same value is in the body as `retry_after`. |
| `X-Request-Id` | Always | The HTTP request ID, for correlating one HTTP exchange in your proxy and application logs. If you send a valid `X-Request-Id`, it is echoed. It is never the valuation ID. |
| `X-Valuation-Id` | Valuation results | The valuation ID (`val_…`), the same value as the body's `request_id`. Sent by `POST /v1/valuations` (also for refused and failed outcomes and replays) and `GET /v1/valuations/{id}`. It is what the console and support look up. |
| `Cache-Control` | Always | `no-store`. Do not cache valuation responses in shared caches. |

## Status codes

| Status | Meaning |
| --- | --- |
| `200` | Success. For valuations, `status` is `valued`. |
| `400` | The request is malformed or does not match the schema. |
| `401` | The key is missing, invalid, expired or revoked. |
| `402` | No credits, or the key's monthly credit limit is reached. |
| `403` | The key lacks a scope or a market, or the workspace is suspended. |
| `404` | Unknown resource or catalogue ID. |
| `409` | Idempotency conflict, or the same request is still running. |
| `413` | The request is larger than 1 MB. |
| `422` | The vehicle cannot be valued as described (a recorded refusal). |
| `429` | Rate limit or workspace concurrency limit. Retry after `retry_after`. |
| `500`, `502`, `503`, `504` | A service problem. Most are retryable; check `retryable` and `fix`. |

Every code, its meaning and how to recover is listed under [errors & retries](/docs/errors).

## Limits

| Limit | Default |
| --- | --- |
| Valuation, selling-time, read-back and account requests (valuations bucket) | 60 per minute per workspace |
| Normalization and VIN, HSN/TSN and plate lookups (vehicles bucket, counted separately) | 60 per minute per workspace |
| Catalogue requests | 120 per minute per workspace |
| Live valuations, selling-time forecasts and normalizations in progress at once | 4 per workspace |
| Test ones in progress at once | 4 per workspace, separate from live |
| Test-key requests that identify a vehicle | 10 per minute, 100 per hour and 300 per day per workspace |
| Request body | 1 MB, including inline images |
| Images per valuation | 8 |
| Description length | 20,000 characters |

See [rate & concurrency limits](/docs/concepts/limits). Contact sales if you need more.

## Versioning

The API is versioned in the path (`/v1`). The contract version (currently 0.9.0) is in the [OpenAPI document](/openapi.yaml) (`info.version`) and in the MCP server's `serverInfo.version`.

> **Beta: expect frequent changes until 1.0.** While the contract version is below 1.0, fields, endpoints, error codes, MCP tools and behaviour may change often, and some changes may break existing integrations. Every change is announced in the [changelog](/docs/changelog), with breaking changes marked. From 1.0, changes within `/v1` will be additive only.

Build clients that ignore fields, error codes, warning codes and enum values they do not recognise, and match on codes rather than messages. Pin the contract version you tested against and check the changelog before you upgrade.

## Client libraries

There are no official SDKs yet. The API is small enough to call with any HTTP client, and the examples in these docs show curl, Ruby (`net/http`), Python (`requests`) and JavaScript (`fetch`). You can also generate a client from the [OpenAPI contract](/openapi.yaml).
