VIN Decoder & Vehicle Recalls
Pricing
from $1.20 / 1,000 vehicle decodeds
VIN Decoder & Vehicle Recalls
Decode up to 500 VINs per run with official NHTSA vPIC data: make, model, year, trim, body, engine, fuel, drive and plant, with an honest complete/partial/invalid status. Adds NHTSA recall campaigns for each make/model/year.
Pricing
from $1.20 / 1,000 vehicle decodeds
Rating
0.0
(0)
Developer
Cliqto Media
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 days ago
Last modified
Categories
Share
VIN Decoder & Vehicle Recalls turns a list of VINs into clean vehicle rows with official NHTSA vPIC data: make, model, model year, trim, body, engine, fuel, drive and assembly plant. For each make, model and year it also lists the NHTSA recall campaigns, with component, summary, consequence, remedy and report date.
It is made for fleet lists, dealer and auction inventories, insurance and lending checks, and data cleaning. No login and no API key are needed. A run with the three example VINs takes about 4 seconds and costs about $0.010.

Contents
- What it does
- Quick start
- Use cases
- Input
- Output
- Pricing
- Limits
- API and integrations
- Troubleshooting
- FAQ
- Data source
- Support
What it does
The Actor sends your VINs to the official NHTSA vPIC batch decoder, 50 VINs per request. It writes one vehicle row per VIN with a clear decodeStatus:
complete— vPIC decoded the VIN with no warnings (vPIC error code0).partial— the vehicle is known, but vPIC reported a problem, for example a wrong check digit (code1) or an incomplete VIN with*(code6). The decoded fields are still filled.invalid— vPIC could not find the make or the model year, or the value is not a VIN. The row says why (decodeError,errorText) and may have a fix insuggestedVin. It costs $0.0001.
Then the Actor groups your vehicles by make, model and year and asks the NHTSA Recalls API once per group. Ten VINs of the same 2019 Camry need only one recall request. The recall campaigns go to a separate Recalls dataset, one row per campaign and model, with the list of your VINs in appliesToVins.
Your VINs go only to vPIC. The Recalls API gets only make, model and year.
Good fit
- Decode a fleet, inventory or lead list of up to 500 VINs in one run.
- Find which NHTSA recall campaigns exist for the models in your list.
- Clean VIN columns: find typos, wrong check digits and values that are not VINs.
Not a fit
- This is not a VIN history report: no owners, accidents, title or mileage.
- It does not tell you whether a recall applies to one exact VIN, or whether the repair was done. Recalls are listed for the make, model and year. Check one VIN at nhtsa.gov/recalls or with the manufacturer.
- vPIC covers vehicles sold in the United States. Other VINs may come back
partialorinvalid.
Quick start
- Open the Input tab.
- Keep the three example VINs in VINs (
vins) or paste your own, one per line. - Keep Include NHTSA recalls on.
- Click Start.
- Open the Output tab. Vehicles has one row per VIN. Recalls has the recall campaigns.
Expected result for the example: 3 vehicle rows (2003 Honda Accord complete, 2023 Tesla Model 3 complete, 2011 BMW X3 partial because the VIN has a *) and 40 recall rows (24 + 12 + 4).
Use cases
| Buyer job | Input | Output | Key fields |
|---|---|---|---|
| Decode a fleet or dealer inventory | vins | Vehicles | make, model, modelYear, trim, bodyClass, fuelTypePrimary |
| See open safety campaigns for the models you own or sell | vins, includeRecalls: true | Recalls | nhtsaCampaignNumber, component, consequence, remedy, appliesToVins |
| Clean a VIN column before import | vins, includeRecalls: false | Vehicles | decodeStatus, checkDigitValid, errorCodes, suggestedVin |
| Plan EV or fuel analytics | vins | Vehicles | electrificationLevel, fuelTypePrimary, engineCylinders, displacementL |
Input
| Field | Name in the form | Type | Required | Default / prefill | Allowed values | What it changes |
|---|---|---|---|---|---|---|
vins | VINs | array of strings | yes | prefill: 3 example VINs | 1–500 values | The VINs to decode. Spaces, dashes and case are ignored. Duplicates are decoded once. Use * for an unknown position, for example 5UXWX7C5*BA. |
includeRecalls | Include NHTSA recalls | boolean | no | true | true / false | true adds recall rows for each decoded make/model/year. false only decodes; it is faster and costs less. |
matchCandidateModels | Try NHTSA model names | boolean | no | true | true / false | When the recall index does not know the decoded model name, look for up to 3 similar NHTSA model names. See model names. |
Notes:
- Empty lines are ignored and counted in
RUN_SUMMARYwarnings. A list with no values fails with a clear message. - If none of the values can be a VIN (for example only
hello!), the run fails with a clear message, no rows and no row charges. - Values that look like a VIN but are wrong still go to vPIC, because vPIC can suggest a fix (
suggestedVin). They come back asinvalid($0.0001 each).
Input example
{"vins": ["1HGCM82633A004352", "5YJ3E1EA6PF384836", "5UXWX7C5*BA"],"includeRecalls": true,"matchCandidateModels": true}
Output
The run has three outputs, all in the Output tab:
| Output | Where | What is inside |
|---|---|---|
| Vehicles | default dataset, view vehicles | one row per input VIN |
| Recalls | dataset recalls, view recalls | one row per recall campaign and make/model/year |
| Run summary | key-value store record RUN_SUMMARY | counts, warnings, request statistics |
The Export button on the run page exports the default dataset only (vehicles). To export recalls, open Recalls in the Output tab, or use the API link shown there.
Vehicle row example
Trimmed. Every vehicle row has the same keys; unknown values are null.
{"rowType": "vehicle","inputIndex": 1,"vin": "1HGCM82633A004352","decodeStatus": "complete","errorCodes": ["0"],"checkDigitValid": true,"make": "HONDA","model": "Accord","modelYear": 2003,"trim": "EX-V6","bodyClass": "Coupe","vehicleType": "PASSENGER CAR","engineCylinders": 6,"displacementL": 3,"engineHp": 240,"fuelTypePrimary": "Gasoline","electrificationLevel": null,"driveType": null,"plantCity": "MARYSVILLE","plantCountry": "UNITED STATES (USA)","recallLookupStatus": "found","recallCount": 24,"recallCampaignNumbers": ["19V182000", "19E068000", "19V499000"],"note": "Recalls are listed for the make/model/year, not confirmed for this VIN. Check the VIN at https://www.nhtsa.gov/recalls.","provider": "NHTSA vPIC","fetchedAt": "2026-10-11T06:18:26.048Z"}
Vehicle fields
| Field | Type | Meaning |
|---|---|---|
rowType | string | Always vehicle in this dataset (recall in the Recalls dataset). |
inputIndex | integer | Position in your input after duplicates are removed. Sort by it to get your order back. |
inputVin, vin | string | Your value and the normalized VIN. |
decodeStatus | string | complete, partial, invalid or error (vPIC was down; the row is free). |
decodeError | string or null | Short reason for invalid and error rows, for example vPIC could not identify the make. vPIC's own text is in errorText. null for complete and partial. |
errorCodes, errorText, additionalErrorText | array, string | vPIC error codes and their text, for example ["1"] wrong check digit, ["6"] incomplete VIN. |
checkDigitValid | boolean or null | Local check of the 9th character. null for incomplete VINs. |
suggestedVin, possibleValues | string or null | vPIC hint for wrong positions. |
make, manufacturer, model, modelYear, trim, series | string, integer | Vehicle identity. |
bodyClass, vehicleType, doors | string, integer | Body. |
engineCylinders, displacementL, engineHp, engineModel | integer, number, string | Engine. displacementL has 1 decimal. |
fuelTypePrimary, fuelTypeSecondary, electrificationLevel | string | Fuel and electrification, for example Electric, BEV (Battery Electric Vehicle). |
driveType, transmissionStyle, gvwr | string | Drive, transmission, weight class. |
plantCity, plantState, plantCountry, plantCompanyName | string | Assembly plant. |
recallLookupStatus | string | found (campaigns listed), none_reported (the model is in the NHTSA recall index with 0 campaigns for this year), candidates_found (recalls of similar model names, check them), not_in_recall_index (the recall index does not know this model name; it does not mean no recalls), skipped_incomplete_decode (no make, model or year), not_requested or error. |
recallLookupError | string or null | Why the recall lookup failed. |
recallCount, recallCampaignNumbers | integer, array | Recall campaigns listed for this make/model/year. |
recallModelCandidates | array | NHTSA model names that may match, for example SILVERADO 1500. |
note, provider, sourceUrl, fetchedAt | string | Reminder about recalls, source, single-VIN vPIC link, time of the request. |
vPIC returns an empty string for many unknown values. The Actor turns empty strings and Not Applicable into null, and turns numbers into numbers.
Recall row example
Trimmed.
{"rowType": "recall","nhtsaCampaignNumber": "19V182000","campaignType": "vehicle","make": "HONDA","model": "ACCORD","modelYear": 2003,"matchType": "exact","vehicleModelDecoded": "Accord","appliesToVins": ["1HGCM82633A004352"],"component": "AIR BAGS:FRONTAL:DRIVER SIDE:INFLATOR MODULE","consequence": "An explosion of an inflator within the driver frontal air bag module may result in sharp metal fragments striking the driver, front seat passenger or other occupants resulting in serious injury or death.","remedy": "Honda will notify owners, and dealers will replace the driver's air bag inflator with an alternate inflator, free of charge. ...","reportReceivedDate": "2019-03-06","parkIt": false,"parkOutside": false,"overTheAirUpdate": false,"provider": "NHTSA Recalls API"}
Recall fields
| Field | Type | Meaning |
|---|---|---|
nhtsaCampaignNumber | string | NHTSA campaign number, for example 19V182000. |
campaignType | string | vehicle, equipment, tire, child_seat or unknown. |
make, model, modelYear | string, integer | The make/model/year in the recall index. |
matchType | string | exact, or candidate_model when the row comes from a similar NHTSA model name. Check the model before you rely on it. |
vehicleModelDecoded | string | The model name vPIC returned for your VINs. |
appliesToVins | array | Your VINs with this make/model/year. It does not mean each VIN is affected. |
manufacturer, component, summary, consequence, remedy, notes | string | Recall text from NHTSA. |
reportReceivedDate | string | Date NHTSA got the report, YYYY-MM-DD. |
parkIt, parkOutside, overTheAirUpdate | boolean or null | NHTSA flags: do not drive, park outside, fix by software update. |
nhtsaActionNumber | string or null | Related NHTSA investigation. |
provider, sourceUrl, fetchedAt | string | Source, query link, time of the request. |
Status of the run
| Situation | What you see |
|---|---|
| All good | Run SUCCEEDED; status message like "3 vehicle row(s) (2 complete, 1 partial, 0 invalid, 0 decode error) and 40 recall row(s)." |
| Some VINs are wrong | Run SUCCEEDED; those rows are invalid with decodeError and errorText. |
| No recalls for a model | recallLookupStatus: none_reported, recallCount: 0. |
| Recalls API failed | recallLookupStatus: error. It is never shown as "0 recalls". Vehicle data is kept. |
| vPIC failed | Rows decodeStatus: error (free), run status message explains it. |
| No value can be a VIN | Run FAILED with a message. |
Pricing
This Actor uses pay per event. You pay only for these events:
| Event | When | Price |
|---|---|---|
| Actor start | once per run (per GB of memory; the default 256 MB = 1 event) | $0.002 |
| Vehicle decoded | each complete or partial vehicle row | $0.0014 ($0.0012–0.0013 on paid Apify plans) |
| Recall record | each recall row | $0.0001 |
| Invalid VIN checked | each invalid vehicle row (reason and suggestedVin) | $0.0001 |
error rows (NHTSA was unavailable) are free. Platform usage is included in the price.
| Example | Events | Price |
|---|---|---|
| The 3 example VINs with recalls | 1 start + 3 vehicles + 40 recalls | $0.0102 |
| 100 VINs, recalls off | 1 start + 100 vehicles | $0.142 |
| 100 VINs of 20 models with recalls (about 7 recalls per model) | 1 start + 100 vehicles + about 140 recalls | about $0.156 |
| 500 VINs, recalls off | 1 start + 500 vehicles | $0.702 |
500 values that all turn out invalid | 1 start + 500 invalid | $0.052 |
The number of recall rows depends on the models: a 2003 Honda Accord has 24 campaigns, a new model may have none. Set Maximum cost per run in the run options to cap the price. When the cap is near, the Actor stops writing new rows and says so in RUN_SUMMARY.
Limits
- Up to 500 VINs per run. Time depends mostly on the number of unique make/model/year groups: one recall request per group. In our tests 500 VINs of 92 groups finished in about 60 seconds with 256 MB of memory. For more VINs, start several runs.
- The Actor waits at least 0.3 seconds between requests to NHTSA and retries a few times on errors. It stops source work after 240 seconds, keeps the rows it has and ends with status
CAPPEDorPARTIALinRUN_SUMMARY. - NHTSA data can change at any time. Each row has
fetchedAt.
API and integrations
- API: start the Actor with the Apify API and read the vehicles and recalls datasets. The run's Output tab shows both API links.
- Export: CSV, JSON, Excel and more from each dataset.
- Schedules and webhooks: run the same VIN list every week with an Apify schedule to get fresh recall lists.
Use with AI agents (MCP)
- MCP server with only this Actor:
https://mcp.apify.com?tools=cliqtomedia/vin-decoder-vehicle-recalls - Smallest useful input:
{"vins": ["1HGCM82633A004352"]} - Key output fields:
decodeStatus,make,model,modelYear,recallLookupStatus,recallCampaignNumbers; recall rows:nhtsaCampaignNumber,component,remedy. - A run with a few VINs takes about 4 seconds and costs about $0.01. Up to 500 VINs per run.
Troubleshooting
A VIN comes back invalid
Check decodeError and suggestedVin. A common reason is a typo, or the letters I, O or Q, which a VIN never has. Non-US VINs may also be unknown to vPIC.
A VIN comes back partial
Read errorCodes and errorText. Code 1 means the check digit is wrong: the VIN may have a typo. Code 6 means the VIN is incomplete. The decoded fields are still useful, but check them.
Why is recallLookupStatus not_in_recall_index?
vPIC and the recall index sometimes use different model names. For example vPIC says Silverado, the recall index has SILVERADO 1500 and SILVERADO 2500. With matchCandidateModels on, the Actor adds recalls from up to 3 similar names and marks them candidates_found and matchType: candidate_model. With more than 3 similar names it only lists them in recallModelCandidates. This status does not mean the model has no recalls.
Some recalls do not apply to my VIN
That is expected. Recalls are listed for the whole make, model and year. A campaign can cover only some engines, plants or build dates. Check the VIN at nhtsa.gov/recalls.
FAQ
Do I need an NHTSA account or API key?
No. Both NHTSA APIs are public.
Does it tell me if the recall repair was done?
No. NHTSA's public recall API does not have repair status per VIN.
Why are recalls in a separate dataset?
Vehicles and recalls have different columns. Two datasets give two clean tables. Join them by vin and appliesToVins, or by make, model and modelYear.
Is the output in my input order?
Rows are written in groups. Sort by inputIndex to get your order back.
Data source
Data: NHTSA vPIC and the NHTSA Recalls API, U.S. government public information. This Actor is not affiliated with or endorsed by NHTSA or the U.S. DOT. NHTSA makes no guarantees about accuracy.
Support
Use the Issues tab of this Actor. Add the run ID and the VINs or status you saw. Do not send API tokens or private data.