NHTSA's VIN Decoder (vPIC): What It Returns and Where It Stops
What NHTSA's vPIC API returned for real VINs, the quirks to plan for, and why no VIN decoder can tell you a car's options or color.
In short
vPIC is NHTSA's public VIN decoder. It needs no key, costs nothing, and is built from the VIN filings carmakers submit to NHTSA, so it's good at what a VIN encodes: year, make, model, body, engine and often the trim. It can't tell you a specific car's options, paint or option prices, because a VIN doesn't contain them. Those come from the manufacturer's build data.
We use vPIC ourselves. It's one of the sources our decoder asks when a VIN's maker isn't in our tables, so this isn't a takedown. On October 21, 2026 we ran it on a few VINs from our docs. Here's what came back, and what no decoder can tell you, ours included.
What vPIC is
vPIC, the Product Information Catalog Vehicle Listing, is NHTSA's record of how carmakers assign VINs. Manufacturers file that information under 49 CFR Part 565, and vPIC decodes a VIN by matching it against those filings.
The endpoint most people want returns one flat object per VIN:
curl "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues/WP0AF2A99KS165242?format=json"There's also DecodeVINValuesBatch, which takes up to 50 VINs per request. NHTSA doesn't publish a rate limit. Its docs say traffic is managed by "an automated traffic rate control mechanism", so pace big jobs.
What it returned for a 2019 Porsche 911 GT3 RS
The response has 154 fields. For WP0AF2A99KS165242, 52 of them had a value. These are the ones most apps need:
| Field | vPIC value |
|---|---|
ModelYear | 2019 |
Make, Model | PORSCHE, 911 |
Series, Trim | Type 991, GT3 RS |
BodyClass | Coupe |
DisplacementL, EngineCylinders, EngineHP | 4, 6, 520 |
DriveType | RWD/Rear-Wheel Drive |
TransmissionSpeeds | 7 |
BasePrice | 187500 |
PlantCity, PlantCountry | STUTTGART-ZUFFENHAUSEN, GERMANY |
Note | Curb Weight (lbs): 3153-3517 |
That's more than vPIC usually gets credit for: the trim, the horsepower, even the base price.
Look at the last row, though. The curb weight is a range because vPIC describes every car that shares this VIN pattern, not this one car. Usually that's the same thing. Not always.
What no VIN decoder can tell you
Here's the build data for that same car, from our OEM Build Data API:
{ "exteriorColor": { "GT Silver Metallic": "#A2A2A2" }, "interiorColor": { "Black": "#000000" }, "transmission": "PDK 7-speed auto-shift manual", "options": { "474": "Front Axle Lift System", "QR5": "Chrono Package with Preparation For Lap Trigger", "U2": "GT Silver Metallic", "XDH": "Wheels Painted in Satin Platinum" }, "optionsMsrp": 8950}None of that is in the VIN. In a North American VIN, positions 4 to 8 describe the vehicle (model line, series, body, engine and restraints), position 9 is a check digit, 10 is the model year, 11 is the plant, and 12 to 17 are the serial number. There's no slot for paint, packages or what they cost.
So a decoder that gives you options from a VIN alone is either reading build data behind the scenes or guessing. Ask any vendor which, us included.
When the VIN can't settle the trim
We also ran a 2026 Tesla Cybertruck, 7G2CEHED3TA100196. vPIC returned the make, model and year, a 123 kWh battery and "Dual Motor" as the drive unit. It left Trim empty.
Our decoder doesn't name a trim for that VIN either. As our docs show, it returns "trim": null with the candidates, most likely first:
"trims": ["Dual Motor", "Premium", "Base"]Both answers are honest. Several trims share that VIN pattern, and only the car's build data or window sticker can say which it is. A decoder that always returns exactly one trim is guessing some of the time.
Quirks to plan for
- Empty means unknown. Most of the 154 fields come back as empty strings. An empty
BlindSpotMondoesn't mean the car has no blind spot monitoring. - Read
ErrorCode, not the error text. Our 2022 Silverado ZR2 and the Cybertruck both decoded cleanly, withErrorCode"0". Both also came back withAdditionalErrorTextsaying "The Model Year decoded for this VIN may be incorrect." - Names come back as filed. Makes are in capitals (CHEVROLET), and model and series are split, so that Silverado is
Model"Silverado" withSeries"1500". Plan on a mapping layer before you show these to people. - 50 VINs per batch and no published rate limit. Fine behind a form. Slow going for a 100,000-row inventory.
- No recalls. vPIC only decodes. NHTSA's recalls API looks recalls up by make, model and year rather than by VIN, so its list for a 2019 911 includes a recall written for the 911 Speedster and 2020 Carrera models. Whether one specific car still has an unfixed recall is a separate question.
When vPIC is enough
vPIC is a good fit when you need the year, make, model, body and engine of US-market vehicles, you can live with capital letters, empty fields and a mapping layer, and your volume is modest or you can pace it.
Look elsewhere when you need:
- A specific car's options, colors or option prices.
- Ranked trim candidates when the VIN can't settle the trim.
- Listings, photos, payments or a per-VIN open recall check next to the decode.
- One key, a rate limit you can plan around, and someone to email when a VIN decodes wrong.
That second list is what we built Auto.dev for. VIN decoding is on every plan, and build data starts on Growth.
Questions
Have other questions? Check out our docs or .
Does the NHTSA VIN decoder API need an API key?
No. vPIC is public and needs no key or account. NHTSA manages traffic automatically, so pace large jobs.
How many VINs can vPIC decode at once?
Up to 50 per request with DecodeVINValuesBatch. Longer lists need more than one request.
Can a VIN tell you a car's options or color?
No. A VIN encodes the model line, body, engine, model year, plant and a serial number. Options, paint and option prices come from the manufacturer's build data.
How accurate is vPIC?
It's as good as the filings carmakers submit to NHTSA. Fields that describe a range, like curb weight, cover the whole VIN pattern rather than one car.
Hand this post to your agent
Copy it as Markdown, or open it in the assistant you use.
npm install -g @auto.dev/sdk