DEV Community

Vin Lookup
Vin Lookup

Posted on

A VIN Validation Checklist for Car Marketplace Developers

If you run a car marketplace, classifieds site or dealer tool, the VIN field is your best defense against bad listings, but only if you validate it properly. A check-digit test alone isn't enough. Here's a layered checklist, from cheap input checks to cross-checking the listing.

1. Normalize input

  • Trim whitespace, remove spaces and dashes, uppercase everything.
  • Don't silently "fix" I, O and Q to 1/0. Flag them instead: they're never valid in a modern VIN, and auto-correcting can hide typos or fraud.

2. Structural checks (instant, client-side)

  • Exactly 17 characters for vehicles from model year 1981 onward.
  • Allowed alphabet: A-H J-N P R-Z 0-9.
  • Position 9 check digit passes (North American VINs). Many non-North-American VINs don't use it, so treat a failure on a non-NA WMI as a warning, not an error.
  • Position 10 is a valid model year code (never U, Z or 0).
const VIN_RE = /^[A-HJ-NPR-Z0-9]{17}$/;
export function normalizeVin(raw: string) {
  return raw.replace(/[\s-]/g, "").toUpperCase();
}
export function basicVinErrors(vin: string): string[] {
  const errs: string[] = [];
  if (vin.length !== 17) errs.push("Must be 17 characters");
  if (/[IOQ]/.test(vin)) errs.push("Contains I, O or Q");
  if (!VIN_RE.test(vin)) errs.push("Invalid characters");
  if (/[UZ0]/.test(vin[9] ?? "")) errs.push("Invalid model year code");
  return errs;
}
Enter fullscreen mode Exit fullscreen mode

3. Decode on the server

Call NHTSA's vPIC DecodeVinValues endpoint (free, no key). Check:

  • ErrorCode is 0 (or only informational codes); otherwise show the ErrorText.
  • Make, Model, ModelYear are populated.

Cache results by VIN; specs don't change.

4. Cross-check against the listing

This is where most fraud is caught:

  • Year, make, model in the listing match the decode.
  • Body class (sedan vs SUV vs pickup) matches.
  • Engine and fuel type match when the seller states them (e.g. "V8" vs a decoded 4-cylinder, "electric" vs gasoline).
  • Drive type (AWD/4WD) if advertised.

Auto-fill these fields from the decode and lock or highlight edits that contradict it.

5. Duplicate and reuse detection

  • Flag the same VIN appearing in multiple active listings, especially from different sellers or cities.
  • Flag VINs previously removed for fraud.
  • Watch for listings that reuse a VIN with different photos or colors.

6. Point buyers to external checks (don't overclaim)

You can't verify history from a decode. Link buyers to:

  • NHTSA's VIN recall lookup,
  • NICB VINCheck (theft and insurance total-loss records),
  • an NMVTIS-approved title history provider.

Label clearly that your decode confirms factory specs only.

7. UX details that matter

  • Show the decoded summary ("2019 Honda Civic LX sedan, 2.0L") right under the VIN field so sellers catch their own typos.
  • Accept pasted VINs from photos/OCR, but always show the result for confirmation.
  • Keep pre-1981 vehicles on a separate path: their VINs are shorter and don't follow the 17-character standard.

Summary

Normalize, check structure, decode, cross-check the listing, detect duplicates, and be honest about what a decode can't tell you. That catches most typos and a large share of fake listings before a buyer ever sees them.


Disclosure: I build VIN Lookup, a free VIN decoder based on NHTSA data.

Top comments (0)