VIN decodingNeoVINNHTSA vPICREST API

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. DecodeVINValuesBatch takes 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:

Requestbash
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:

vPIC response (trimmed)json
{
  "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:

Requestbash
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:

NeoVIN response (trimmed)json
{
  "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_price values add up to installed_options_msrp in 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 trim and version before the listing goes live. The NeoVIN guide covers these builds in detail.

Using both: a free check first, NeoVIN when the build matters

  1. VIN from a form or feed
  2. Free vPIC check
  3. NeoVIN if the build matters
  4. 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:

decode.tsts
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 recallsByVehicle endpoint 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

  1. Decode a VIN from your own data on vPIC and note which fields come back empty.
  2. Create a free account and decode the same VIN with NeoVIN; the first-call guide covers what the Free plan includes.
  3. Wire decode.ts into your intake so NeoVIN calls go only where the build matters.
  4. Keep the NeoVIN Decoder docs and the vPIC API page open while you build.

Start building on the Free tier.

The Free tier is for development and testing, on the same endpoints you will use in production. When you go live, pick a plan on the pricing page.

Building with a coding assistant? Give it the free Docs MCP, so it looks up documented parameters instead of guessing them.

More use cases

All use cases