NHTSA VIN Decoder API — Batch vPIC VIN Lookup avatar

NHTSA VIN Decoder API — Batch vPIC VIN Lookup

Pricing

from $2.75 / 1,000 results

Go to Apify Store
NHTSA VIN Decoder API — Batch vPIC VIN Lookup

NHTSA VIN Decoder API — Batch vPIC VIN Lookup

Batch-decode VINs via NHTSA vPIC into compact, normalized rows: make, model, year, body class, drivetrain, engine, GVWR, and plant country. One clean row per VIN. Built for fleet, auto-insurance underwriting, and used-car marketplace enrichment. Keyless government data.

Pricing

from $2.75 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 days ago

Last modified

Share

Decode a batch of VINs into clean, normalized rows using the official NHTSA vPIC database (keyless, free, US government source). Every VIN returns one row with a stable 125-field schema — make, model, year, body class, drivetrain, engine, transmission, plant, occupant protection and the full NHTSA ADAS/active-safety field set — ready to join straight into your fleet, underwriting, or marketplace pipeline.

VIN decoder API for bulk vehicle lookups — make, model, year, body class, drivetrain, engine, GVWR, plant, safety systems, normalized and batchable.

Who it's for

  • Fleet & telematics teams — enrich vehicle rosters from just the VIN.
  • Auto insurers & underwriting — standardized vehicle attributes plus the safety-equipment fields that drive rating.
  • Used-car marketplaces & dealership tools — auto-fill listing specs at scale.
  • Warranty & lending providers — verify class, drivetrain and weight rating.
  • Data teams — a stable-schema VIN feed you can decode thousands at a time.

Decode confidence — read this before you trust a row

NHTSA's ErrorCode is the entire correctness contract of a VIN decode, and it is a closed vocabulary of 15 published values. vPIC returns combined codes, and 0 genuinely co-occurs with warnings.

Measured live on 2026-08-01, on this actor's own example VIN:

/decodevinvalues/1HGCM82633A004352?modelyear=2005
-> ErrorCode "0,12" Make=HONDA Model=Accord ModelYear=2005
/decodevinvalues/1HGCM82633A004352?modelyear=1999
-> ErrorCode "0,12,14" Make=HONDA Model="" ModelYear=1999

That VIN is a 2003 Accord. Code 12 is "Model Year Warning — the model year entered for decoding does not match the model year based on the 10th position in VIN. Decoded data may not be accurate." Earlier versions of this actor reported both rows as decode_valid: true.

So decode_valid now means exactly one thing:

decode_validMeaning
truevPIC returned ErrorCode exactly "0" — decoded clean, check digit correct.
falsevPIC answered, and the decode is not clean. Read decode_status, error_codes and additional_error_text.
nullvPIC did not answer. A transport failure is not a statement about the VIN.

decode_status gives the full picture: clean, clean_with_warnings (vPIC decoded it but flags the data as possibly inaccurate), partial (some vehicle data alongside error codes — an incomplete VIN still returns make and model), invalid, unavailable, or unknown.

Other guarantees:

  • The closed vocabulary is asserted live on every run. If NHTSA adds or removes an ErrorCode value, the run fails rather than classifying rows by guesswork.
  • A positive canary and a negative control run before anything is billed. A known-good VIN must decode clean; a VIN containing I, O and Q (letters that cannot appear in a VIN) must not. If the decoder ever starts answering 0 for everything, the run fails instead of publishing a fleet of confident false decodes.
  • Truncation is never silent. VINs dropped by maxVins are logged and counted in vins_truncated on every row.
  • If vPIC answers for no VIN in the run, the run fails and bills nothing.

Example input

{
"vins": [
"1HGCM82633A004352",
"JH4KA7561PC008269",
{ "vin": "5UXWX7C5XBA000000", "modelYear": 2011 }
],
"extended": false,
"maxVins": 10000
}

Each item is a plain VIN string, or { "vin": "...", "modelYear": 2013 } to help vPIC disambiguate older VINs. Supplying a modelYear that conflicts with position 10 of the VIN produces ErrorCode 12 and model_year_warning: true — which is exactly the case this actor now reports honestly.

A * can stand in for the check digit or unknown positions; a partial VIN decodes with decode_status: "partial" (measured: 5UXWX7C5*BA returns BMW X3 2011 with ErrorCode 6).

Output fields

Every row carries the same 125 fields; a field vPIC did not populate is null.

Identity and status

FieldDescription
vinThe VIN as requested.
decode_validtrue only when ErrorCode is exactly "0". null when vPIC did not answer.
decode_statusclean, clean_with_warnings, partial, invalid, unavailable, unknown.
error_codeThe raw vPIC ErrorCode, e.g. "0", "0,12", "1,7,400".
error_codesThe same value split into tokens.
error_textvPIC's own ErrorText.
error_code_meaningsEach token expanded from NHTSA's published vocabulary.
additional_error_textvPIC's free-text explanation, e.g. "Invalid character(s): 1:I, 2:O, 3:Q.".
suggested_vinvPIC's corrected VIN, ! marking each rejected position, e.g. "1G1YY22!965105693".
has_decode_warningsTrue when any "data may be wrong" code (2, 3, 4, 8, 11, 12, 14) was returned.
model_year_warningTrue when ErrorCode includes 12.
check_digit_validFalse when ErrorCode includes 1.
requested_model_yearThe modelYear you supplied, if any.
vpic_statusok or unavailable.
vpic_errorTransport error behind unavailable.
extended_decodeWhether the extended endpoint was used.
decoded_field_countHow many fields vPIC actually populated (45 for the example Accord, 70 for a 2018 Tesla Model 3, 4 for an unregistered manufacturer).
vins_truncatedVINs dropped by maxVins and therefore not decoded.
retrieved_atISO timestamp of the decode.

Vehicle

make, model, model_year, manufacturer, manufacturer_id, make_id, model_id, vehicle_type, body_class, series, series_2, trim, trim_2, vehicle_descriptor, doors, gvwr, gvwr_to, curb_weight_lb, ncsa_body_type, ncsa_make, ncsa_model, base_price_usd, note.

Engine and drivetrain

engine_cylinders, displacement_l, displacement_cc, displacement_ci, engine_hp, engine_hp_to, engine_model, engine_manufacturer, engine_configuration, valve_train_design, fuel_injection_type, turbo, cooling_type, other_engine_info, fuel_type_primary, fuel_type_secondary, drive_type, transmission_style, transmission_speeds, axles, wheels, wheel_base_short, wheel_base_type, wheel_size_front, wheel_size_rear, steering_location, brake_system_type, brake_system_desc, top_speed_mph.

Electrification

electrification_level, ev_drive_unit, battery_type, battery_kwh.

Body configuration

bed_type, body_cab_type, seats, seat_rows, entertainment_system, trailer_type, trailer_body_type, trailer_length_ft, bus_type, bus_floor_config_type, custom_motorcycle_type, motorcycle_chassis_type, motorcycle_suspension_type. vPIC answers "Not Applicable" for categories that do not apply to the vehicle; that is vPIC's own answer and is preserved rather than nulled.

Occupant protection and active safety

air_bag_loc_front, air_bag_loc_side, air_bag_loc_curtain, air_bag_loc_knee, air_bag_loc_seat_cushion, seat_belts_all, other_restraint_system_info, pretensioner, abs, esc, traction_control, tpms, forward_collision_warning, cib, pedestrian_aeb, blind_spot_monitoring, blind_spot_intervention, lane_departure_warning, lane_keep_system, lane_centering_assistance, adaptive_cruise_control, park_assist, rear_visibility_system, rear_cross_traffic_alert, rear_automatic_emergency_braking, daytime_running_light, keyless_ignition, dynamic_brake_support, auto_reverse_system, automatic_pedestrian_alerting_sound, semiautomatic_headlamp_beam_switching, adaptive_driving_beam, active_safety_sys_note.

Manufacturing

plant_country, plant_state, plant_city, plant_company_name.

Populating the optional columns. Coverage is genuinely vehicle-dependent — NHTSA's own response says a missing value means "NHTSA does not have data on the specific variable", not that the feature is absent. Measured 2026-08-01: a 2003 Honda Accord populates 45 fields, a 2018 Tesla Model 3 populates 66 (including electrification_level and the ADAS set), a 2014 Peterbilt 388 populates 37, and an unregistered manufacturer populates 4. additional_error_text and suggested_vin populate on VINs with errors (the example above with IOQ1234567890ABCD). The sparse fields all have a verified populating VIN: ncsa_* on 29 of 33 VINs sampled, plant_company_name on 19, engine_manufacturer and brake_system_type on a 2013 Ford F-150 (1FTFW1ET5DFC10312), battery_kwh on a 2016 Nissan Leaf (1N4BZ0CP0GC300000), trailer_length_ft and cooling_type on a trailer VIN (4X4TSMH23FS000000), and blind_spot_intervention, lane_centering_assistance and rear_automatic_emergency_braking on a 2023 Tesla Model Y (7SAYGDEE0PF600000). Five fields that never populated across 47 diverse VINs were removed rather than shipped as permanently empty columns. The remaining sparse fields also have a recorded populating VIN from the same census: series and series_2 on a 2017 Toyota Camry (4T1BF1FK5HU123456) and a 2018 Hyundai Tucson (KM8J3CA46JU622173), wheel_base_type, top_speed_mph and brake_system_desc on the Camry, engine_hp_to on a Mack truck (1M2AX07C2FM020000), wheel_size_front, wheel_size_rear, curb_weight_lb and entertainment_system on a 2017 Toyota RAV4 (JTMWFREV0HD100000), active_safety_sys_note on the Tucson, and air_bag_loc_seat_cushion on the RAV4. vpic_error is null on a healthy run — that is good news, not a dead column.

Use as an MCP tool

Exposed to AI agents via mcp.apify.com as a "decode these VINs" tool. The three-state contract matters here: an agent must not read decode_valid: null as "invalid VIN", and must not treat decode_valid: false on a clean_with_warnings row as "no data" — the vehicle fields are populated, they are just caveated by NHTSA.

FAQ

Why is decode_valid false on a row that clearly decoded? Because vPIC returned a warning code alongside 0 — almost always code 12, a model-year mismatch. Check decode_status, error_code_meanings and model_year_warning. The vehicle data is there; NHTSA is telling you it may not be accurate.

What is the batch limit? This actor decodes serially so one bad VIN cannot take down the rest of the batch. NHTSA's own DecodeVINValuesBatch endpoint caps at 50 VINs per request (measured: 50 returns Count: 50; 51 and 100 both return Count: 0).

Does extended return more fields? It returns the same 154 field names but populates roughly three more of them per VIN (measured on three VINs, 2026-08-01).

Is this a determination? No. It decodes the manufacturer's VIN submission to NHTSA. It is not a title, odometer, accident or recall check.

Data source (keyless, no anti-bot)

  • https://vpic.nhtsa.dot.gov/api/vehicles/decodevinvalues/{vin} (and decodevinvaluesextended).
  • https://vpic.nhtsa.dot.gov/api/vehicles/GetVehicleVariableValuesList/Error Code — the published ErrorCode vocabulary, asserted live on every run.

Pricing (Pay Per Result)

Billed per dataset record returned: one row per VIN, including VINs that vPIC reports as invalid (a verified negative is an answer). Runs that fail a drift assertion, or lose vPIC entirely, emit nothing and bill nothing.