Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
VIN Decoder & Recalls icon

VIN Decoder & Recalls

Decode VINs in bulk and get open US safety recalls on the same row: make, model, year, trim, engine, plant, airbags, plus recall component and remedy.

19 runs on Apify $0.0009 per VIN decoded ($0.9 / 1,000)
Run this in the cloudRun on Apify →

Developer & Research Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust vins, includeRecalls, maxItems (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.0009 per VIN decoded = $0.9 per 1,000

You are charged forWhenPrice
VIN decodedOne vehicle decoded from its VIN, with any open safety recalls. VINs that cannot be decoded are never charged.$0.0009

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-20, and they are what you are actually charged.

Inputs

FieldWhat it doesType
vinsOne or more 17-character Vehicle Identification Numbers. Up to 1,000 per run. Dashes and spaces are stripped, letter case does not matter, and duplicates are dropped before anything is charged. A VIN identifies a vehicle, not a person - this Actor looks up no owner, registration or title data.array
includeRecallsOn by default. Each decoded vehicle gets its open US safety recall campaigns attached - component, summary, consequence and the manufacturer's remedy. Recall lookups are cached per make, model and year inside the run, so a list of the same few models costs very little extra time. Turn it off if you only want the specification decode; the price per VIN is the same either way.boolean
maxItemsA hard stop on how many of the VINs above are decoded, so a long pasted list cannot run away with your budget. Keep it low while you are testing - you pay per decoded vehicle. Hard ceiling 1,000 per run.integer
proxyUrlsLeave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.array

What you get

A structured dataset — each result includes fields like:

vinmakemodelmodelYeartrimbodyClassvehicleTypedriveTypefuelTypePrimaryrecallLookuprecallCount

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

Related tools in Developer & Research Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

GitHub Scraper iconDeveloper & Research Tools

GitHub Scraper

Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.

18 use cases

Stack Overflow / Stack Exchange Scraper iconDeveloper & Research Tools

Stack Overflow / Stack Exchange Scraper

Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.

2 use cases

Package Registry Scraper (npm + PyPI) iconDeveloper & Research Tools

Package Registry Scraper (npm + PyPI)

Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.

2 use cases

arXiv Scraper iconDeveloper & Research Tools

arXiv Scraper

Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.

2 use cases

OpenAlex Scholarly Works Scraper iconDeveloper & Research Tools

OpenAlex Scholarly Works Scraper

Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.

2 use cases

Crossref Scholarly Works Scraper iconDeveloper & Research Tools

Crossref Scholarly Works Scraper

Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.

2 use cases

See all Developer & Research Tools →

VIN Decoder & Recalls API (NHTSA)

Paste VINs, get vehicles back. Each 17-character VIN becomes one row carrying what the US federal vehicle record says the car is (make, model, year, trim, engine, drivetrain, assembly plant, airbags, ABS, stability control), with every open US safety recall for that make, model and year attached to the same row, including what the fault is, what it can do, and the fix the manufacturer has to provide free.

The awkward part first, because it decides whether this is the right purchase: this is the federal specification and recall record, not a vehicle history report. It cannot tell you whether a car was crashed, flooded, stolen, clocked or salvaged, and it holds nothing at all about whoever owns it. If that is what you need, you need a history report, and no amount of VIN decoding will substitute for one.

  • Up to 1,000 VINs per run, decoded 50 at a time in a single request rather than one at a time.
  • No API key, no account, no cookies, no browser. The source is a free US government service.
  • A VIN that does not decode is a free row that says why, not a charged row full of blanks.
  • Recall lookups are cached inside the run, so 400 VINs across a handful of models cost a handful of lookups.
  • Runs with empty input return a labelled sample row, free, so you can see the shape first.

Price

$0.90 per 1,000 vehicles, plus a $0.0006 start fee per run (one per run, whatever the row count).

This is a flat rate on every plan, free or paid. There are no volume tiers, no minimum spend, no subscription and no add-on fees. What you read here is what you pay on day one and on day four hundred.

VehiclesTotal cost
100$0.0906
1,000$0.9006
10,000$9.0006
100,000$90.0006

Rows that are not charged, such as the sample row, an invalid VIN or a vehicle NHTSA has no record of, do not appear in these totals at all.

What is actually charged

  • One vin-decoded event per vehicle row written to the dataset. Nothing else is metered per row.
  • Free: the sample row an empty run returns, and every diagnostic row: a blocked target, a dead URL, a search that matched nothing. Those rows all carry "charged": false.
  • A VIN that is not 17 characters, or that carries letters no VIN contains, is rejected before it reaches the network and charged nothing.
  • A VIN the federal record has no vehicle for, which is common for cars never sold in the United States, is a free diagnostic row rather than a charge.
  • Duplicate VINs in your list are collapsed before anything is looked up, so pasting the same VIN twice bills once.
  • If the recall service cannot be reached at all, the decoded vehicle is still handed over, but free, with a row saying the recall half is missing.
  • A run that finds nothing costs the start fee and nothing more.
  • Rows never leave the dataset without a charge, and are never charged without a row.

Input

{
  "vins": [
    "1HGCM82633A004352",
    "JTDKARFU2J3064306",
    "3GCUKREC5JG123456"
  ],
  "includeRecalls": true,
  "maxItems": 25
}
FieldWhat it does
vinsThe VINs, as a list. Dashes, spaces and lower case are all fine; they are cleaned before anything is sent. Up to 1,000 per run.
includeRecallsOn by default. Turn it off for a specification-only decode, which is faster on long lists. The price per vehicle does not change either way.
maxItemsA hard stop on how many of your VINs get decoded, so a long pasted list cannot run away with the bill. Default 25, ceiling 1,000.
proxyUrlsLeave empty. Fill it in only if you want the traffic to leave through proxy servers you already pay for, as http://user:pass@host:port.

Run it with empty input and you get one clearly labelled sample row, free, so you can see the output shape before you spend anything.

Output

One row per vehicle. A real row from a real run:

{
  "ok": true,
  "charged": true,
  "recordType": "vehicle",
  "vin": "JTDKARFU2J3064306",
  "make": "TOYOTA",
  "model": "Prius",
  "modelYear": 2018,
  "trim": "Two Eco/Three/Three Touring/Four/Four Touring",
  "bodyClass": "Hatchback/Liftback/Notchback",
  "vehicleType": "PASSENGER CAR",
  "driveType": "4x2",
  "fuelTypePrimary": "Gasoline",
  "recallLookup": "ok",
  "recallCount": 1,
  "recalls": [
    {
      "campaignNumber": "18V579000",
      "reportReceivedDate": "2018-09-05",
      "component": "ELECTRICAL SYSTEM:WIRING",
      "summary": "Toyota Motor Engineering & Manufacturing (Toyota) is recalling certain 2016-2018 Toyota Prius vehicles.  A portion of the engine wire harness connected to the hybrid Power Control Unit (PCU), could contact the cover at this connection and wear, causing an electrical short circuit.",
      "consequence": "An electrical short can increase the risk of a fire.",
      "remedy": "Toyota will notify owners, and dealers will inspect the engine wire harness assembly and replace it if damage is found.  A protective sleeve or protective tape will be included to prevent any future damage.  These repairs will be performed free of charge.  The recall began October 30, 2018.  Owners may contact Toyota customer service at 1-888-270-9371.  Toyota's number for this recall is J0T.",
      "notes": "Owners may also contact the National Highway Traffic Safety Administration Vehicle Safety Hotline at 1-888-327-4236 (TTY 1-800-424-9153), or go to www.safercar.gov.",
      "manufacturer": "Toyota Motor Engineering & Manufacturing",
      "parkIt": false,
      "parkOutSide": false,
      "overTheAirUpdate": false
    }
  ],
  "series": "ZVW50L/ZVW51L",
  "doors": 5,
  "engineCylinders": 4,
  "displacementL": 1.8,
  "engineHorsepower": 96,
  "electrificationLevel": "Strong HEV (Hybrid Electric Vehicle)",
  "transmissionStyle": "Continuously Variable Transmission (CVT)",
  "transmissionSpeeds": null,
  "manufacturer": "TOYOTA MOTOR CORPORATION",
  "plantCountry": "JAPAN",
  "plantCity": "TOYOTA CITY",
  "plantState": "AICHI",
  "gvwr": "Class 1: 6,000 lb or less (2,722 kg or less)",
  "abs": "Standard",
  "esc": "Standard",
  "tpms": "Direct",
  "airBagLocFront": "1st Row (Driver and Passenger)",
  "airBagLocSide": "1st Row (Driver and Passenger)",
  "airBagLocCurtain": "All Rows",
  "seatBeltsAll": "Manual",
  "recallModelMatched": "Prius",
  "nhtsaErrorCodes": "1",
  "nhtsaErrorText": "1 - Check Digit (9th position) does not calculate properly",
  "vehicleDescriptor": "JTDKARFU*J3",
  "scrapedAt": "2026-09-20T08:30:44.584Z"
}

Field notes

  • recallLookup: the one field to read before trusting recallCount. ok means the recall service answered and the campaigns below are what it returned. none means it answered and this vehicle is not in its recall index. unavailable means the count is unknown rather than zero, for one of two reasons: the decode came back without a model name, so there is nothing to match on, or the two federal endpoints disagreed, one listing the model as recalled while the other returns nothing for it. skipped means you turned recalls off. Never read a zero here as a clean bill of health without checking this field first.
  • recallCount: how many campaigns are attached. Only meaningful when recallLookup is ok or none.
  • recalls: the full campaign text, with its number, date reported, component, a plain-English summary of the fault, its consequence, and the remedy the manufacturer owes you. parkIt and parkOutSide are the federal "stop driving it" and "do not park it indoors" flags.
  • recallModelMatched: the model name the recall service actually matched. Usually the same as model; on trucks it is often more specific, because the decode says "Silverado" and the recall index files them as "SILVERADO 1500", "2500" and "3500" separately.
  • modelYear: the model year, which is not the calendar year the car was built.
  • nhtsaErrorCodes: whatever the decoder flagged. Code 1, "check digit does not calculate", is extremely common on perfectly real VINs and does not mean the decode is wrong.
  • trim: often a slash-separated list of the trims that share one VIN pattern, because a VIN does not always narrow to a single trim.
  • engineHorsepower: present for most petrol and hybrid vehicles, usually absent on electric ones.
  • series: the manufacturer series or chassis code, where the record has one.

Every real row carries "charged": true. Sample rows carry "_sample": true and diagnostic rows carry "_diagnostic": true with an errorCode you can filter on, and neither is ever billed.

How it works

  • VINs go to the federal decoder in batches of fifty in one request. Sending them one at a time measured roughly five times slower on the same twenty VINs, and the Actor is priced on what it costs to run, so the batch is the whole design rather than a nicety.
  • Every decode is checked against what came back, not against the HTTP status. The decoder answers 200 for gibberish too, with an empty make and an error code buried in the body, so a row only counts as a vehicle when there is actually a make and a model year in it.
  • Recalls are looked up per make, model and year, and cached for the rest of the run. A fleet list with two hundred Silverados and a hundred F-150s is two lookups, not three hundred.
  • When a lookup comes back empty, the federal recall index is consulted for the exact model names it files that make and year under, and the closest of those is retried, preferring the one matching the VIN's own series, so a 1500's recalls never land on a 3500.
  • Requests go out one at a time. The recall service refuses an address that pushes it, and refuses it for minutes, so the run stays deliberately slow rather than fast and blocked.

What people use it for

  • Dealers and wholesalers running an inbound list of VINs before the cars are listed, so an open airbag or fuel-pump campaign turns up before a customer finds it.
  • Fleet and rental operators checking a whole fleet on a schedule and diffing recallCount against last week to see only what is new.
  • Insurance and claims teams normalising a book of VINs into make, model, year, body class and safety equipment for rating, without typing any of it.
  • Anyone building a car marketplace or a listing feed who needs specifications filled in from the VIN alone rather than from whatever the seller typed.
  • Researchers and journalists pulling the recall record for a model year across a list of real vehicles instead of clicking through one lookup form at a time.

What a VIN does and does not tell you here

A VIN identifies a vehicle, not a person. This Actor looks up nothing about an owner, a registration, a title or an address, and there is no input that would let it. What it returns is the manufacturer's own description of how that car left the factory, as filed with the US regulator, plus the safety campaigns raised against that make, model and year since.

Two consequences worth knowing before you buy:

  • Recalls are matched at make, model and year, because that is the level the public federal recall service works at. A campaign that only covers part of a model year, whether a range of build dates, one plant or one engine, will still appear on every vehicle of that model year. Read the summary; it names the range.
  • Whether a specific car has actually had its recall work done is not public data. Only the manufacturer knows that, and you get it from their own VIN lookup or a franchised dealer. recallCount is "campaigns that apply", never "repairs outstanding".

Reading the output

Every run writes three kinds of row, and they are easy to tell apart:

  • Real rows carry "charged": true and "recordType": "vehicle". One billed event each, and the count of these rows always equals the number of events you were billed for.
  • The sample row carries "_sample": true and "charged": false. There is exactly one, it only appears when you ran with no VINs, and it exists so you can see the output shape before spending anything.
  • Diagnostic rows carry "_diagnostic": true, "charged": false and an errorCode you can switch on: BAD_INPUT when a value was not a 17-character VIN, NO_RESULTS when the federal record holds no vehicle for it, RECALL_LOOKUP_FAILED when the vehicle decoded but the recall service could not be reached, NETWORK when the decoder itself could not be reached, TIME_BUDGET when the run ran out of time before reaching a VIN.

One thing to expect on a long list of bad VINs: the first fifty failures each get their own row, and the rest are collapsed into a single row with a skipped array naming every remaining VIN and its reason. Nothing is hidden, but the row count will be lower than the number of VINs you sent. And if the run gets through 150 VINs in a row without producing a single vehicle, it stops and says so rather than grinding through the rest of a list that is clearly not VINs.

If you only want the data, filter on charged == true. The dataset is its own invoice.

Limitations

  • United States only. This is the US federal vehicle record, so a car never certified for sale in the US, which covers most European and Japanese domestic-market vehicles, decodes partially or not at all, and has no recall record here.
  • Not a vehicle history report. No accident history, no title or salvage brand, no odometer readings, no theft record, no ownership or service history. None of that is in the source.
  • No owner or registration data of any kind, by design and by law.
  • Pre-1981 VINs are not 17 characters and are rejected. The standardised VIN only starts with the 1981 model year.
  • Recalls come from the public federal service, which matches at make, model and year. It cannot tell you whether a particular car falls inside a campaign's build-date range, and it cannot tell you whether the work has been done.
  • The two federal recall endpoints sometimes disagree: one lists a model as having campaigns while the lookup returns nothing for it. Measured across 45 common US vehicles, 40 returned recalls and 5 hit that gap. Those rows say recallLookup: "unavailable" rather than claiming zero recalls, so you can tell an unknown from a clean sheet.
  • How completely a VIN decodes depends on what the manufacturer filed. Older and low-volume vehicles come back with more empty fields than a recent mass-market one, and no amount of re-running changes that.
  • Manufacturer-specific recalls and service campaigns that were never filed federally do not appear. Neither do recalls issued outside the United States.
  • The hard ceiling is 1,000 VINs per run. Split longer lists across runs.
  • Because the recall service throttles hard, long lists of wildly different vehicles take minutes rather than seconds. A list that is mostly the same few models is much faster.

Questions

Is this a vehicle history report?

No, and it cannot be turned into one. This is the federal specification decode plus the federal recall record. Accidents, titles, odometer readings and ownership are not in the source and are not returned. If a car's past is what you need, buy a history report.

Can I look up who owns a vehicle?

No. A VIN identifies a car, not a person, and nothing here touches registration or owner records. There is no input field that would let you, and there will not be one.

What happens if a VIN is wrong or made up?

You get one free diagnostic row saying which it was: not 17 characters, characters that are not valid in a VIN, or no vehicle on file. The run carries on to your other VINs. You are never billed for a VIN that did not produce a vehicle.

Why does a row say the check digit does not calculate?

That is error code 1 from the decoder and it is very common, including on VINs read straight off a real windscreen. It means the ninth character did not match the arithmetic, usually because of a transcription slip, and the rest of the VIN still decodes. Treat it as a hint to re-read the VIN, not as a failure.

Does recallCount of 0 mean the car is clean?

Only when recallLookup says none. If it says unavailable, the federal service returned nothing for a model its own index lists as recalled, so the honest answer is "unknown" and the row says so instead of pretending it is zero.

Can I run this on a schedule?

Yes. Nothing is held between runs, so the same VIN list on a schedule is safe. Diff on recallCount and the campaign numbers in recalls to see only what is new.

Do I need a proxy or an API key?

Neither. The source is a free US government service and the run brings its own egress. The proxy field exists only for callers who specifically want traffic leaving through servers they already own.

How do I get exactly the rows I paid for?

Filter the dataset on "charged": true. Sample and diagnostic rows are always false, and the number of charged rows always equals the number of billed events.