Docs menu

Docs Tutorials / Python: decode a VIN and list its model's recalls

Python: decode a VIN and list its model's recalls

Decode a 17-character VIN, then list every recall NHTSA filed for that make, model and model year, with links to the official notices.

You need a free key (get one; it takes about a minute) in the environment variable RECALLDB_KEY. Keep the key on a server or your own machine, never in a web page.

The code

Two requests: POST /v1/vin (the VIN goes in the body and is not stored) and GET /v1/vehicles/{make}/{model}/{year}.

vin_check.py
"""Decode a VIN with RecallDB and list the recalls NHTSA filed for that model and year.

    pip install requests
    RECALLDB_KEY=rdb_... python3 vin_check.py 1HGCM82633A004352
"""
import os
import sys
from urllib.parse import urlparse

import requests

API = os.environ.get("RECALLDB_API", "https://recalldb.app")
HEADERS = {"Authorization": f"Bearer {os.environ['RECALLDB_KEY']}"}

vin = sys.argv[1] if len(sys.argv) > 1 else "1HGCM82633A004352"

# 1. Decode the VIN (it goes in the body, never in the URL; RecallDB does not store it).
r = requests.post(f"{API}/v1/vin", headers=HEADERS, json={"vin": vin}, timeout=20)
r.raise_for_status()
decoded = r.json()["data"]
if decoded["status"] != "ok":
    print(f"Could not use this VIN: {decoded['status']}")
    sys.exit(0)
car = decoded["vehicle"]
print(f"{car['year']} {car['make']} {car['model']}")

# 2. The model-year recalls. The decode answer links the model page; its path has the make and model ids.
_, _, make, model, year = urlparse(decoded["model_recalls_page"]).path.split("/")
r = requests.get(f"{API}/v1/vehicles/{make}/{model}/{year}", headers=HEADERS, timeout=20)
r.raise_for_status()
body = r.json()
recalls = body["data"]["recalls"]
print(f"{body['data']['recall_count']} recall(s) filed for this model and year:")
for rec in recalls:
    print(f"  {rec['date']}  {rec['id']}  {rec['component'] or ''}")
    print(f"      {rec['source']['official_url']}")

# Recalls are filed by model and year: not every car of this model is part of each one.
print("To check this exact car, enter the VIN at https://www.nhtsa.gov/recalls or ask the carmaker.")
print(f"{body['attribution']['text']} ({body['attribution']['url']})")

Run it

Terminal
pip install requests
RECALLDB_KEY=rdb_your_key python3 vin_check.py 1HGCM82633A004352

What the answer means

  • The list is every recall filed for that model and year. Not every car of that model is part of each recall.
  • To know whether one exact car has an open recall, enter its VIN at nhtsa.gov/recalls or ask the carmaker. The script says so too.
  • status can be none-found or not-covered: that never means the car has no recalls.

Reference: POST /v1/vin, GET /v1/vehicles.