VIN decoder API: NHTSA vPIC vs MarketCheck NeoVIN
What NHTSA's free vPIC API returns for a VIN and what it leaves out, when it is all you need, and what NeoVIN adds, with the same VIN decoded by both.
MarketCheck6 min read
For developers choosing a VIN decoder for listings, appraisals, insurance quotes or fleet tools
Developers who search for a VIN decoder API, or for an NHTSA VIN decoder API, often start with vPIC, the free decoder the National Highway Traffic Safety Administration runs, and look at commercial decoders once a job needs more than vPIC returns.
In short. vPIC is free and needs no key or registration. It decodes what manufacturers register with NHTSA about how their VINs are assigned: make, model, model year, body, engine, plant and safety equipment. For the 2020 F-150 below it returns no trim and no price. NeoVIN returns the trim and version, each installed option with its code and price, both colors and an MSRP breakdown that adds up. Use vPIC to check and classify VINs, and NeoVIN when a detail page or an appraisal depends on the exact build.
What vPIC is, and what it is built from
vPIC is NHTSA's Product Information Catalog Vehicle Listing. As of Oct 2026, its API page and FAQ say the following:
- Source. The dataset is populated from the information motor vehicle manufacturers submit to NHTSA under Part 565, the rule for how VINs are assigned, and that catalog is what decodes a VIN.
- Access. No licensing or registration: the FAQ calls the services free for use by the public under NHTSA's Open Data initiatives. No daily cap applies, though an automated rate control limits traffic; NHTSA asks that large batch runs go at night (Eastern time) or on weekends.
- Formats. JSON, XML or CSV, as key-value pairs (
DecodeVin) or one flat row per VIN (DecodeVinValues). Partial VINs decode too, with*for unknown characters. - Batches.
DecodeVINValuesBatchtakes up to 50 VINs per request, and standalone vPIC databases are available to download. - Coverage. The FAQ puts decode confidence near 99% for model years 1995 onward for most major brands, 60 to 65% for 1980 to 1994, and has no data before 1980.
The vPIC variable list has 144 variables. Trim, Series and Base Price are among them, filled when the manufacturer supplies them. Nothing in the list covers paint colors or factory options and packages.
One VIN through both decoders
The VIN is 1FTEW1C59LKE56394, the documented NeoVIN sample. Here is the vPIC flat decode, as it came back in Oct 2026:
curl "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues/1FTEW1C59LKE56394?format=json&modelyear=2020"vPIC returns one flat row of 154 fields, every value a string, and 93 of them are empty for this VIN. Trimmed to the fields compared below:
{
"Count": 1,
"Results": [
{
"VIN": "1FTEW1C59LKE56394",
"ModelYear": "2020",
"Make": "FORD",
"Model": "F-150",
"Trim": "",
"Series": "",
"BasePrice": "",
"BodyClass": "Pickup",
"BodyCabType": "Crew/Super Crew/Crew Max",
"DriveType": "4x2",
"DisplacementL": "5",
"EngineCylinders": "8",
"EngineHP": "395",
"PlantCity": "KANSAS CITY",
"PlantState": "MISSOURI",
"VehicleDescriptor": "1FTEW1C5*LK",
"ErrorCode": "0",
"ErrorText": "0 - VIN decoded clean. Check Digit (9th position) is correct"
}
]
}The same VIN through NeoVIN, from the NeoVIN Decoder docs:
curl "https://api.marketcheck.com/v2/decode/car/neovin/1FTEW1C59LKE56394/specs?api_key=YOUR_API_KEY"Trimmed to two of the eighteen installed options and one feature group:
{
"vin": "1FTEW1C59LKE56394",
"squish_vin": "1FTEW1C5_LK",
"year": 2020,
"make": "Ford",
"model": "F-150",
"trim": "XLT",
"trim_confidence": "mc_build_specs|cf_equipments|exact_match",
"version": "XLT SuperCrew 5-1/2 Box",
"drivetrain": "RWD",
"engine": "5.0L V8",
"msrp": 40020,
"delivery_charges": 1695,
"installed_options_msrp": 10085,
"combined_msrp": 51800,
"exterior_color": { "code": "E7", "name": "Velocity Blue Metallic", "base": "Blue" },
"interior_color": { "code": "FB", "name": "Black Unique Sport Cloth 40/Console/40 Front-Seats", "base": "Black" },
"installed_options_details": [
{ "code": "302A", "name": "Equipment Group 302A - Luxury", "msrp": "4345", "sale_price": "2595" },
{ "code": "17B", "name": "BLIS (Blind Spot Information System) with Cross-Traffic Alert", "msrp": "590", "sale_price": "590" }
],
"high_value_features": {
"17B": [
{ "category": "Safety & Driver Assist", "description": "Blind Spot System" },
{ "category": "Safety & Driver Assist", "description": "Cross Traffic Collision Avoidance" }
]
}
}Both decoders agree on what the VIN pattern says. vPIC's VehicleDescriptor and NeoVIN's squish_vin keep the same ten characters (the first eight, then the model year and plant codes) with a placeholder for the check digit, and both read a 2020 F-150 pickup with a 5.0-liter V8 and two-wheel drive. The difference is the build:
| For this VIN | vPIC | NeoVIN |
|---|---|---|
| Trim | Empty | XLT, version XLT SuperCrew 5-1/2 Box |
| Cab and bed | Crew/Super Crew/Crew Max | SuperCrew with the 5-1/2 box, from version |
| Options and packages | No field | 18 installed, each with code, MSRP and sale price |
| Colors | No field | Velocity Blue Metallic (E7) outside, black sport cloth inside |
| Price | Base Price empty | MSRP 40,020, delivery 1,695, options 10,085, combined 51,800 |
| Blind spot warning | Empty; where filled, the field says Standard, Optional or Not Available for the model | Installed on this truck, through option 17B |
The NeoVIN guide explains why the build matters for value: for a 2020 F-150 known only from its VIN pattern, the original MSRP could be anywhere from $38,795 to $59,245.
Side by side
| NHTSA vPIC | MarketCheck NeoVIN | |
|---|---|---|
| Access | Free, no key or registration | API key; the Free plan includes 500 calls a month |
| Built from | Manufacturers' VIN-assignment submissions to NHTSA | Manufacturer data, dealer listings and window stickers, matched to the VIN |
| Trim | A field, filled when the manufacturer supplies it | trim, version and trim_confidence |
| Options and packages | Not covered | installed_options_details, plus features and high_value_features keyed by option code |
| Colors | Not covered | Exterior and interior: code, name and base color |
| Prices | A Base Price field, filled when supplied | msrp, delivery_charges, installed_options_msrp and combined_msrp |
| Safety | Fields for safety systems, each marked standard or optional for the model where the manufacturer supplied it | Installed safety options by option code, and safety ratings |
| Partial VINs | Yes, with * |
No, full 17-character VINs only |
| Batches | Up to 50 VINs per request | 100 to 3,000 VINs per job, an Enterprise offering enabled on request |
When vPIC is enough
vPIC answers questions about the VIN pattern, and many jobs only ask those:
- Validating input.
ErrorCode"0" reads "VIN decoded clean", with the check digit confirmed, which catches mistyped VINs on a form before you spend anything else. - Year, make and model. A service booking or a parts lookup often needs nothing finer.
- Classifying a fleet. Body class, vehicle type, GVWR class and fuel type sort a list of VINs into groups.
- Safety equipment by model. vPIC says whether a safety system is standard or optional on the model, where the manufacturer supplied it.
- Partial VINs and bulk jobs. Wildcards handle a VIN with unreadable characters, and the downloadable databases handle volumes a rate-controlled API should not carry.
When the job needs NeoVIN
NeoVIN answers questions about the individual car:
- Vehicle detail pages. Trim, packages, colors by their manufacturer names, and high-value features such as heated seats or blind spot monitoring that shoppers filter on.
- Window-sticker style pricing. The MSRP breakdown reconciles: the eighteen options'
sale_pricevalues add up toinstalled_options_msrpin this sample. - Appraisals and trade-ins. Two cars from the same VIN pattern can differ by thousands in options, and the decode shows which one you have.
- Listing checks. Compare the trim a seller typed with the decoded
trimandversionbefore the listing goes live. The NeoVIN guide covers these builds in detail.
Using both: a free check first, NeoVIN when the build matters
- VIN from a form or feed
- Free vPIC check
- NeoVIN if the build matters
- Detail page or appraisal
vPIC works as a free first pass. Validate and classify with vPIC, and spend a NeoVIN call only on the VINs whose build you need:
const VPIC = 'https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues'
const NEOVIN = 'https://api.marketcheck.com/v2/decode/car/neovin'
export async function vpic(vin: string, modelYear?: number) {
const url = new URL(`${VPIC}/${vin}`)
url.searchParams.set('format', 'json')
if (modelYear) url.searchParams.set('modelyear', String(modelYear)) // vPIC recommends sending it
const res = await fetch(url)
if (!res.ok) throw new Error(`vPIC returned ${res.status}`)
const [row] = (await res.json()).Results
// ErrorCode "0" reads "VIN decoded clean"; anything else, show ErrorText to a person
return { clean: row.ErrorCode === '0', errorText: row.ErrorText, year: Number(row.ModelYear), make: row.Make, model: row.Model, body: row.BodyClass }
}
export async function neovin(vin: string) {
const url = new URL(`${NEOVIN}/${vin}/specs`)
url.searchParams.set('api_key', process.env.MARKETCHECK_API_KEY ?? '')
const res = await fetch(url)
if (res.status === 422) return null // invalid VIN or a failed decode
if (!res.ok) throw new Error(`NeoVIN returned ${res.status}`)
return res.json()
}
export async function decode(vin: string, needBuild: boolean) {
const basic = await vpic(vin)
if (!basic.clean || !needBuild) return { basic, build: null }
return { basic, build: await neovin(vin) } // cache by VIN: a factory build never changes
}Between the two sits MarketCheck's Basic VIN Decoder, GET /v2/decode/car/{vin}/specs, which returns year, make, model, trim, engine and drivetrain with an is_valid flag, and no options or prices.
Limits to design around
- vPIC is a public resource. Respect its rate control, and for bulk work use the downloadable databases or run batches at the off-hours NHTSA asks for.
- Empty means unknown in vPIC. Its response message says a missing value means NHTSA has no data on that variable, not that the feature is absent.
- NeoVIN needs full VINs. Squish VINs are not accepted, and a 422 means an invalid VIN or a failed decode. With
include_generic=true, generic specifications come back as a fallback. - NeoVIN calls count against your plan. Each decode is one call, so cache decodes by VIN.
- Recalls are a separate API on both sides. NHTSA's
recallsByVehicleendpoint at api.nhtsa.gov takes a make, model and model year; MarketCheck's AutoRecalls takes a VIN and is a partner API that needs a paid plan and an accepted agreement.
Who this is for
Developers at dealers, marketplaces, appraisal tools, insurers and fleet operators who need to decide which decoder each step of a workflow deserves.
Start here
- Decode a VIN from your own data on vPIC and note which fields come back empty.
- Create a free account and decode the same VIN with NeoVIN; the first-call guide covers what the Free plan includes.
- Wire
decode.tsinto your intake so NeoVIN calls go only where the build matters. - Keep the NeoVIN Decoder docs and the vPIC API page open while you build.