Quickstart

Your first three calls: resolve free text to refs, then query with them.

The Cardog API is VIN identity, canonical specs, listings, live market data, and recalls behind one key.

Base URL: https://api.cardog.app

The ref is the API. Every parameter is an entity ref (make:tesla, model-year:honda/cr-v/2026) or a VIN. Free text is accepted in exactly one place — GET /v2/entities/resolve — which returns refs with confidence. The API never silently fuzzy-matches: an unknown ref is a 400 that names the ref.

1. Get an API key

  1. Create an account at cardog.app
  2. Create a key under Account → API
  3. Copy it immediately — it is shown once

Send it on every request, either way works:

bash
-H "x-api-key: $CARDOG_API_KEY"
# or
-H "Authorization: Bearer $CARDOG_API_KEY"

2. Pick your client

curl works everywhere; the SDKs give you the same surface with types. Both are generated from the same contract as this reference:

bash
npm install @cardog/api   # TypeScript / JavaScript
pip install cardog        # Python

3. Resolve free text to refs

Start from whatever you have — a search box string, a typo, a VIN-less description — and get refs back:

curl "https://api.cardog.app/v2/entities/resolve?q=2021%20civic" \
  -H "x-api-key: $CARDOG_API_KEY"

The response is a list of candidates ordered best-first, each with a confidence score. best is null when nothing clears the confidence floor — the API never guesses for you. Hold on to the refs you get back; they are the currency for every other call.

If you already have a VIN, decode it instead — the identity card carries the same refs plus links to adjacent resources:

curl "https://api.cardog.app/v2/vin/1HGCM82633A123456" \
  -H "x-api-key: $CARDOG_API_KEY"

4. Query with refs

Refs plug into every group — listings, quotes, specs, recalls. Not every parameter is a ref, and the distinction is worth learning once:

  • Ref parameters name a node in the graph: make, model, and the path segment on quotes, specs and recalls. They take a full {domain}:{key} string and reject anything else with a 400 that names the offender.
  • Scalar parameters are ordinary filters: year.min, year.max, price.max, limit. They take numbers.

So on listings, a make is a ref and a year is a range — make=make:tesla and year.min=2022 in the same query is normal, not a mixed metaphor. Listings filters on make and model refs only; there is no model-year= filter, because a model year on this surface is expressed as a year range. To query a single model year as a node, use the groups that take one in the path (quotes, specs, recalls, safety), as below.

# Listings: make is a ref, year is a range — both, in one query
curl "https://api.cardog.app/v2/listings/search?make=make:tesla&year.min=2022&limit=5" \
  -H "x-api-key: $CARDOG_API_KEY"

# Live market quote for an instrument
curl "https://api.cardog.app/v2/quotes/model-year:honda%2Fcr-v%2F2026" \
  -H "x-api-key: $CARDOG_API_KEY"

# Recalls scoped to an entity — make:, model: or model-year: all work
curl "https://api.cardog.app/v2/recalls/entity/model-year:honda%2Fcr-v%2F2026" \
  -H "x-api-key: $CARDOG_API_KEY"

The ref grammar

A ref is domain:slug:

PartMeaningExamples
domainThe entity domainmake, model, model-year, fuel-type, squish, recall
slugThe entity's path in that domain; hierarchical slugs use /tesla, mini/hardtop, honda/cr-v/2026

Rules that matter:

  • In URL paths, slashes inside a ref must be URL-encoded: /v2/entities/model-year:honda%2Fcr-v%2F2026
  • In query strings, refs are passed raw: ?make=make:tesla
  • Ref filters are repeatable: ?make=make:tesla&make=make:rivian
  • List every domain with a bare GET /v2/entities (the domain index), browse a domain's members with GET /v2/entities?domain=make, or dereference any ref with GET /v2/entities/{ref}

Every v2 response carries a links block — rel → server-relative path — so adjacent resources (entity → quotes, recalls, listings, specs) are one traversal away. Follow the links instead of building URLs by hand.

Errors are instructions

Every non-2xx body is the same envelope: a machine-dispatchable code, a message naming the offending input, a hint saying what to do next, and nearest-ref suggestions where computable. See the Errors guide.

Credits

Metered responses carry X-Credits-* headers, and GET /v2/pricing is the machine-readable rate card (no auth required). Budget mid-task from those — never from hardcoded numbers.

For agents

Every docs page has a markdown twin: append .md to any docs URL, or send Accept: text/markdown. The whole platform — auth, errors, ref grammar, every operation — is one fetch: /docs.md.