Skip to main content

cardog

The Python SDK for the Cardog API — the system of record for the Canadian vehicle. Decode VINs, resolve names to permanent refs, search live Canadian listings, quote the market, and check Transport Canada + NHTSA recalls behind one key.

pip install cardog
import os

from cardog import Cardog

client = Cardog(api_key=os.environ["CARDOG_API_KEY"])

# Free text enters exactly once. Everything after this takes refs.
result = client.v2.entities.resolve("2021 Civic")
ref = result.best.ref            # "model-year:honda/civic/2021"

identity = client.v2.vin.get("2HGFC2F53MH500001")
recalls = client.v2.vin.recalls("2HGFC2F53MH500001")
quote = client.v2.quotes.get(ref)

Canadian VIN decode coverage is 99.77%. Types and methods are generated from the same OpenAPI contract the API validates against — this SDK and the TypeScript one are siblings, not translations.

Errors are instructions. Every non-2xx v2 response raises a typed CardogAPIError carrying code, hint, docs_url, and nearest-ref suggestions, so a wrong ref is corrected on the next call instead of silently matched to the wrong vehicle.

Whole platform in one fetch: https://cardog.app/docs.md

Quick start — resolve → refs → query

v2 is ref-native: free text enters the API in exactly one place (entities.resolve), everything else speaks canonical refs like make:tesla or model-year:toyota/rav4/2021.

from cardog import Cardog

client = Cardog(api_key="your-api-key")

# 1. Free text → refs with confidence (the front door)
resolved = client.v2.entities.resolve("tesla model y")
best = resolved.best          # None when nothing clears the confidence floor —
                              # the API never guesses for you
print(best.ref)               # "model:tesla/model-y"

# 2. Dereference a ref: node + parents/children + counts + links
detail = client.v2.entities.get(best.ref)
print(detail.name, detail.counts)

# 3. Query with refs — never fuzzy, never guessed
results = client.v2.listings.search(
    filters={
        "makes": ["make:tesla"],
        "price": {"max": 60000},
        "year": {"min": 2022},
    },
    sort="price",
    order="asc",
)
for listing in results.listings:
    print(f"{listing.year} {listing.make} {listing.model} — ${listing.price:,.0f}")

VIN → identity, recalls, market

# VIN → graph identity card (refs, grains, links)
identity = client.v2.vin.get("5YJSA1E26MF420053")
print(identity.make, identity.model, identity.refs.model_year)

# Batch decode (metered per VIN, max 1000) — one bad VIN fails its own row, never the batch
batch = client.v2.vin.batch(["5YJSA1E26MF420053", "1HGCV1F34LA045661"])

# Recalls affecting a VIN (Transport Canada + NHTSA fused)
recalls = client.v2.recalls.vin("5YJSA1E26MF420053")

# VIN → market instrument bridge, quotes, tape
instrument = client.v2.vin.instrument("5YJSA1E26MF420053")
quote = client.v2.quotes.get("model-year:toyota/rav4/2021")
bars = client.v2.tape.history("model-year:toyota/rav4/2021", window="3m")

Errors are instructions

Every non-2xx v2 response raises CardogAPIError carrying the full error envelope — code is machine-dispatchable, hint says what to do next, and suggestions carries nearest-ref candidates so a typo'd ref self-corrects in one turn:

from cardog import Cardog, CardogAPIError

client = Cardog(api_key="your-api-key")

try:
    client.v2.listings.search(filters={"makes": ["make:teslla"]})
except CardogAPIError as e:
    print(e.status_code)   # 400
    print(e.code)          # "unknown_entity_refs"
    print(e.hint)          # "Resolve free text to refs at GET /v2/entities/resolve?q=teslla"
    print(e.docs_url)      # "https://cardog.app/docs/errors#unknown_entity_refs"
    print(e.refs)          # ["make:teslla"]
    for s in e.suggestions or []:
        print(s["invalid"], "→", [n["ref"] for n in s["nearest"]])
        # "make:teslla" → ["make:tesla"]   (advisory — never auto-applied)

Async

AsyncCardog mirrors the whole surface:

import asyncio
from cardog import AsyncCardog

async def main():
    client = AsyncCardog(api_key="your-api-key")
    identity = await client.v2.vin.get("5YJSA1E26MF420053")
    results = await client.v2.listings.search(filters={"makes": ["make:tesla"]})
    await client.close()

asyncio.run(main())

The v2 surface

Group Methods
client.v2.entities browse(domain, ...) · resolve(q, ...) · get(ref)
client.v2.vin get(vin) · batch(vins) · recalls(vin) · listings(vin) · instrument(vin)
client.v2.specs catalog() · sheet(ref, trim=...)
client.v2.listings search(...) · count(...) · facets(...) · by_vin(vin) · by_id(id)
client.v2.instruments search(q=..., limit=...) · get(ref, window=...)
client.v2.quotes get(ref) · get_many(refs)
client.v2.tape live(limit=...) · history(ref, window=...)
client.v2.recalls vin(vin) · entity(ref) · feed() · stats() · get(ref)
client.v2.safety ratings(ref) · complaints(ref, page=..., limit=...)
platform meta client.v2.pricing() · client.v2.openapi() (both unauthenticated)

The machine-readable rate card (pricing()) plus the X-Credits-* response headers let you budget mid-task; openapi() returns the same contract this SDK is generated from.

v1 (legacy)

The pre-1.0 resources keep working unchanged — client.vin.decode(...), client.listings.search(...), client.market, client.recalls, client.charging, client.fuel, and the rest ride under the same client with the same signatures. New integrations should target client.v2.*.

One behavioural note for 1.0: api_key is now optional (Cardog() works) so the unauthenticated platform-meta routes are reachable without a key. Everything else requires a key, exactly as before.

Configuration

client = Cardog(
    api_key="your-api-key",          # or omit for pricing()/openapi() only
    base_url="https://api.cardog.app/v1",  # default; a trailing /v1 is stripped for v2 calls
    timeout=30.0,
    max_retries=2,                   # retries 408/429/5xx with backoff, honours Retry-After
)

Regenerating the v2 surface (maintainers)

make generate    # emit openapi.v2.json from @cardog/contracts, regenerate src/cardog/v2/
make check       # generate twice + assert zero diff + run tests

src/cardog/v2/ (types + group resources) is generated by scripts/generate.py from packages/contracts/dist/openapi.v2.json — do not edit those files by hand. The method map (operationId → Python method) lives in the generator and is validated against the spec on every run.

License

MIT


mcp-name: app.cardog/mcp

Release files for cardog 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cardog 1.0.0
File Size Uploaded
cardog-1.0.0.tar.gz 75.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cardog 1.0.0
File Interpreter ABI Platform
cardog-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 133.7 kB

Release files / cardog-1.0.0.tar.gz

Download URL cardog-1.0.0.tar.gz
Size 75.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9ef704626c5d105a88235c0c19cf1e0b11b390cd7182e1396347ff826cd755dc
BLAKE2b-256 checksum
How to use checksums
9da306f4752f5160ed72836e5ae2508741e7c30627468a4f8a87634f97467bee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release files / cardog-1.0.0-py3-none-any.whl

Download URL cardog-1.0.0-py3-none-any.whl
Size 58.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0153e324fb6101e664dbd7d1b9bdd4dbf83370522d47f8858732a59c2708713f
BLAKE2b-256 checksum
How to use checksums
89933b4fb1bde2621356a3fd22f955ac7a3d43ebceb815106c97fbdde55f4673
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page