All posts

Introducing the Cardog Python SDK: Automotive Data for Python Developers

Cardog Team6 min read
Introducing the Cardog Python SDK: Automotive Data for Python Developers

Introducing the Cardog Python SDK: Automotive Data for Python Developers

We launched the Cardog TypeScript client to bring automotive intelligence to JavaScript and TypeScript developers. Today, we are extending that same power to the Python ecosystem with the official Cardog Python SDK - now available on PyPI.

Python powers everything from data science notebooks to production ML pipelines, Django backends to FastAPI microservices. If you are building automotive applications in Python - whether that is a price prediction model, a dealer inventory tool, or a vehicle history checker - you now have first-class access to the same real-time data that powers Cardog.

bash
pip install cardog

That is all it takes to get started.


Why Python?

When we built the TypeScript client, we heard immediately from Python developers. Data scientists wanted market analytics for pricing models. Backend engineers needed VIN decoding for their Django apps. Researchers wanted access to recall and complaints data for safety analysis.

Python is the language of data. And automotive is fundamentally a data problem - millions of listings, thousands of specifications, decades of safety records. It made sense to bring these worlds together.

The Python SDK provides:

  • Synchronous and asynchronous clients - Use Cardog for sync code or AsyncCardog for asyncio applications
  • Full type safety - Pydantic v2 models for every response, with IDE autocomplete that actually works
  • 12 resource modules - VIN, Listings, Market, Recalls, Charging, Fuel, Research, Locations, Safety, Efficiency, Complaints, and History
  • Automatic retries - Built-in retry logic for rate limits and transient errors via httpx
  • Python 3.9+ - Support for Python 3.9 through 3.13

Quick Start

Install the SDK and initialize a client with your API key:

python
from cardog import Cardog

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

# Decode a VIN
vehicle = client.vin.decode("1HGCM82633A123456")
print(vehicle.components.vehicle.make)   # "Honda"
print(vehicle.components.vehicle.model)  # "Accord"
print(vehicle.components.vehicle.year)   # 2003

Every response is a Pydantic model. Your IDE will autocomplete fields, catch type errors, and provide inline documentation. No more guessing at response structures or hunting through API docs.


VIN Decoding

VIN decoding is the foundation of automotive data. Every vehicle sold in North America since 1981 has a 17-character Vehicle Identification Number that encodes make, model, year, specifications, and more.

Single VIN Decode

python
result = client.vin.decode("5YJSA1E26MF123456")

vehicle = result.components.vehicle
print(f"{vehicle.year} {vehicle.make} {vehicle.model}")  # 2021 Tesla Model S
print(f"Trim: {vehicle.trim}")                           # Long Range
print(f"Body: {vehicle.body_style}")                     # Sedan

The decoder returns comprehensive specifications - engine details, transmission, safety features, dimensions, fuel economy, and more. For EVs, you get battery capacity, range estimates, and charging specs.

Batch Decoding

Processing a fleet or inventory? Decode up to 1,000 VINs in a single request:

python
vins = ["1HGCM82633A123456", "5YJSA1E26MF123456", "WP0AB2A99NS123456"]
results = client.vin.batch(vins)

for vin, data in results.items():
    if data.success:
        print(f"{vin}: {data.vehicle.year} {data.vehicle.make} {data.vehicle.model}")
    else:
        print(f"{vin}: Failed - {data.error}")

VIN from Image

Have a photo of a VIN plate or registration document? Extract and decode it in one call:

python
import base64

with open("vin_photo.jpg", "rb") as f:
    image_data = base64.b64encode(f.read()).decode()

result = client.vin.image(image_data)
print(f"Detected VIN: {result.vin}")
print(f"Confidence: {result.confidence}")

Market Intelligence

This is where the SDK really shines. We track millions of vehicle listings across North America, providing real-time market intelligence that was previously only available to large dealers and auction houses.

Market Overview

Get a comprehensive snapshot of any vehicle's market position:

python
overview = client.market.overview("Honda", "Civic", 2022)

print(f"Total listings: {overview.total_listings}")
print(f"Median price: ${overview.median_price:,.0f}")
print(f"Price range: ${overview.min_price:,.0f} - ${overview.max_price:,.0f}")
print(f"Avg days on market: {overview.avg_days_on_market}")
print(f"Avg mileage: {overview.avg_odometer:,.0f} miles")

Price Distribution

Understand how prices cluster in the market - perfect for visualizations or pricing models:

python
pricing = client.market.pricing("Ford", "F-150", 2023)

for bucket in pricing.histogram:
    print(f"${bucket.min:,} - ${bucket.max:,}: {bucket.count} listings")

# Output:
# $35,000 - $40,000: 1,247 listings
# $40,000 - $45,000: 2,891 listings
# $45,000 - $50,000: 3,156 listings

Geographic Analysis

See how prices vary by region - critical for arbitrage opportunities or regional pricing strategies:

python
geography = client.market.geography("Tesla", "Model 3", 2022)

for region in geography.regions:
    print(f"{region.name}: ${region.median_price:,.0f} ({region.count} listings)")

# Output:
# California: $42,500 (2,341 listings)
# Texas: $39,800 (1,567 listings)
# Ontario: $44,100 (892 listings)

Depreciation Analysis

Understand how mileage affects value - essential for trade-in valuations or residual value predictions:

python
odometer = client.market.odometer("Toyota", "Camry", 2020)

for bracket in odometer.brackets:
    print(
        f"{bracket.min_miles:,}-{bracket.max_miles:,} miles: "
        f"${bracket.median_price:,.0f} ({bracket.count} listings)"
    )

Local Market Data

Get market intelligence scoped to a specific location:

python
local = client.market.local(
    "BMW", "3 Series", 2022,
    lat=43.6532,
    lng=-79.3832,
    radius=50  # km
)

print(f"Local median: ${local.median_price:,.0f}")
print(f"Local listings: {local.total_listings}")
print(f"vs National median: ${local.national_median:,.0f}")

Search our database of millions of active listings across North America:

python
results = client.listings.search(
    makes=["Toyota", "Honda"],
    models={"Toyota": ["Camry", "Corolla"], "Honda": ["Accord", "Civic"]},
    year_min=2020,
    year_max=2024,
    price_min=15000,
    price_max=40000,
    odometer_max=50000,
    body_styles=["Sedan"],
    fuel_types=["Gasoline", "Hybrid"],
    page=1,
    limit=20,
)

print(f"Found {results.meta.total} matching listings")

for listing in results.listings:
    print(f"{listing.year} {listing.make} {listing.model} - ${listing.price:,}")

Build filter UIs with accurate counts:

python
facets = client.listings.facets(makes=["Mercedes-Benz"], year_min=2020)

print("Body Styles:")
for facet in facets.body_styles:
    print(f"  {facet.value}: {facet.count} listings")

print("\nFuel Types:")
for facet in facets.fuel_types:
    print(f"  {facet.value}: {facet.count} listings")

Safety Data: Recalls and Complaints

Safety information is critical for any automotive application. We aggregate data from NHTSA (US) and Transport Canada, making it easy to search and analyze.

Search Recalls

python
# US recalls
recalls = client.recalls.search(
    country="us",
    makes=["Toyota"],
    models=["RAV4"],
    year_min=2019,
    year_max=2024,
)

for recall in recalls.data:
    print(f"Campaign: {recall.campaign_number}")
    print(f"Component: {recall.component}")
    print(f"Summary: {recall.summary}")
    print(f"Affected: {recall.affected_count:,} vehicles")
    print("---")

# Canadian recalls
ca_recalls = client.recalls.search(
    country="ca",
    makes=["Honda"],
    models=["CR-V"],
    year_min=2020,
)

NHTSA Complaints

Consumer complaints often predict future recalls. Search the complaints database:

python
complaints = client.complaints.search(
    makes=["Ford"],
    models=["Explorer"],
    year_min=2020,
    year_max=2023,
    components=["ENGINE", "BRAKES"],
)

for complaint in complaints.data:
    print(f"Date: {complaint.date_received}")
    print(f"Component: {complaint.component}")
    print(f"Mileage: {complaint.mileage:,}")
    print(f"Crash: {complaint.crash_involved}")
    print(f"Description: {complaint.description[:200]}...")
    print("---")

EV Charging and Fuel Stations

For applications that help drivers find fuel or charging:

EV Charging Stations

python
chargers = client.charging.search(
    lat=37.7749,
    lng=-122.4194,
    radius=25,      # km
    min_power=50,   # kW - for DC fast chargers
)

for station in chargers.stations:
    print(f"{station.name}")
    print(f"  Network: {station.network}")
    print(f"  Distance: {station.distance:.1f} km")
    print(f"  Max Power: {station.max_power_kw} kW")
    print(f"  Connectors: {', '.join(station.connector_types)}")

Gas Station Prices

python
fuel = client.fuel.search(
    country="US",
    fuel_type="REGULAR",
    lat=37.7749,
    lng=-122.4194,
    radius=10,
    limit=20,
)

for station in fuel.stations:
    print(f"{station.name}: ${station.price}/gallon")
    print(f"  Updated: {station.last_updated}")

Vehicle Research Database

Access our complete vehicle database - every make, model, year, and trim sold in North America:

Browse Make Lineups

python
toyota = client.research.lineup("Toyota")

for model in toyota.models:
    years = f"{min(model.years)}-{max(model.years)}"
    print(f"{model.name}: {years}")

# Output:
# Camry: 1983-2025
# Corolla: 1968-2025
# RAV4: 1996-2025

Get Model Year Specifications

python
variants = client.research.model_year("Toyota", "Camry", 2024)

for variant in variants:
    print(f"{variant.trim}: ${variant.msrp:,}")
    print(f"  Engine: {variant.engine_type}")
    print(f"  Horsepower: {variant.horsepower}")
    print(f"  MPG: {variant.combined_mpg}")

Async Support

For asyncio applications - FastAPI, async Django, or any async codebase:

python
import asyncio
from cardog import AsyncCardog

async def main():
    client = AsyncCardog(api_key="your-api-key")

    # All methods are async
    vehicle = await client.vin.decode("1HGCM82633A123456")
    overview = await client.market.overview("Honda", "Civic", 2022)

    # Parallel requests
    results = await asyncio.gather(
        client.market.overview("Toyota", "Camry", 2022),
        client.market.overview("Honda", "Accord", 2022),
        client.market.overview("Nissan", "Altima", 2022),
    )

    # Clean up
    await client.close()

asyncio.run(main())

The async client uses the same interface as the sync client - just add await to your calls.


Error Handling

The SDK provides typed exceptions for different error conditions:

python
from cardog import (
    Cardog,
    NotFoundError,
    RateLimitError,
    AuthenticationError,
    APIError,
)

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

try:
    vehicle = client.vin.decode("INVALID-VIN")
except NotFoundError:
    print("VIN not found or invalid")
except RateLimitError as e:
    print(f"Rate limited - retry after {e.retry_after} seconds")
except AuthenticationError:
    print("Invalid API key")
except APIError as e:
    print(f"API error: {e.status_code} - {e.message}")

Common error types:

ExceptionStatusDescription
AuthenticationError401Missing or invalid API key
PermissionError403API key lacks permission
NotFoundError404Resource not found
RateLimitError429Too many requests
ServerError5xxServer error

Configuration

Customize the client for your needs:

python
client = Cardog(
    api_key="your-api-key",
    base_url="https://api.cardog.app/v1",  # default
    timeout=30.0,                          # request timeout in seconds
    max_retries=2,                         # retry on 429/5xx errors
)

The client uses httpx under the hood, providing automatic retries with exponential backoff for rate limits and transient server errors.


Type Safety with Pydantic

Every response is a Pydantic v2 model with full type hints. This means:

  • IDE autocomplete - Your editor knows every field and its type
  • Runtime validation - Responses are validated against the schema
  • Serialization - Easy conversion to dict or JSON
python
overview = client.market.overview("Toyota", "Camry", 2023)

# Your IDE knows these types
median: float = overview.median_price
total: int = overview.total_listings
regions: list[RegionData] = overview.regions

# Serialize to dict or JSON
data = overview.model_dump()
json_str = overview.model_dump_json()

What Developers Are Building

Since opening up beta access, we have seen Python developers build incredible things:

  • Pricing models that predict fair market value using our market analytics
  • Django inventory apps for dealers that sync with live market data
  • Data science notebooks analyzing recall patterns and safety trends
  • FastAPI microservices that power mobile apps with real-time vehicle data
  • CLI tools for quick VIN lookups and market checks
  • ML pipelines training on historical pricing data

We are excited to see what you build.


Documentation and Resources


Get Started

  1. Get an API key at cardog.app
  2. Install the SDK: pip install cardog
  3. Read the docs at docs.cardog.app
python
from cardog import Cardog

client = Cardog(api_key="your-api-key")
vehicle = client.vin.decode("1HGCM82633A123456")
print(f"{vehicle.components.vehicle.year} {vehicle.components.vehicle.make}")

Questions? Issues? Feature requests? Open an issue on GitHub or reach out to api-support@cardog.ai.

We built Cardog to democratize automotive data. With the Python SDK, that data is now accessible to the millions of Python developers worldwide. We cannot wait to see what you create.

bash
pip install cardog

Frequently asked questions