NHTSA Vehicle Recalls & Complaints — US Vehicle Safety avatar

NHTSA Vehicle Recalls & Complaints — US Vehicle Safety

Pricing

from $4.00 / 1,000 recall results

Go to Apify Store
NHTSA Vehicle Recalls & Complaints — US Vehicle Safety

NHTSA Vehicle Recalls & Complaints — US Vehicle Safety

US vehicle safety recalls and owner complaints (crash, fire, injuries, deaths) from the official NHTSA public APIs, per make/model/year in batch. No login. Not affiliated with NHTSA.

Pricing

from $4.00 / 1,000 recall results

Rating

0.0

(0)

Developer

Johnn Mottin

Johnn Mottin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

A used car with an open recall is a legal risk a US dealer cannot afford. Look up US vehicle safety recalls and owner complaints (crash, fire, injuries, deaths) for a batch of vehicles — make + model + model year — straight from the official NHTSA public APIs. No login, no browser.

Not affiliated with, sponsored by, or endorsed by the National Highway Traffic Safety Administration (NHTSA) or the U.S. Department of Transportation. All data comes from the official public NHTSA APIs and remains subject to NHTSA's terms.

Who it's for:

  • Dealers and used-car marketplaces: check open recalls before buying, listing, or selling — selling a used car with an open recall is a legal risk for US dealers.
  • Fleets: batch-audit every vehicle model in the fleet on a schedule.
  • Insurers, warranty and risk teams: structured complaint signals (crash/fire/injuries/deaths per model) for pricing and triage.

How it works

You send a list of vehicles; the Actor queries the official API once per vehicle per mode:

  • Recalls (default): open safety recalls — campaign number, component, summary, consequence, remedy, park-it / park-outside flags.
  • Complaints (opt-in via include): owner complaints filed with NHTSA — ODI number, crash/fire flags, injuries, deaths, components, incident and filing dates.

One vehicle failing (invalid year, API hiccup) never kills the batch: it becomes a controlled entry in STATS.vehicleSummary and the rest continues. You are only charged for records actually written to the dataset — complaints discarded by the per-vehicle cap or date filter cost you nothing.

Input

Copy-paste ready:

{
"vehicles": [
{ "make": "honda", "model": "civic", "modelYear": 2024 },
{ "make": "toyota", "model": "corolla", "modelYear": 2023 }
],
"include": ["recalls", "complaints"],
"maxComplaintsPerVehicle": 50,
"complaintsFiledDaysBack": 365,
"maxResults": 1000
}
FieldTypeDefaultDescription
vehiclesarrayrequired1–200 {make, model, modelYear} objects. Case-insensitive duplicates skipped; invalid entries become INVALID_VEHICLE in STATS.vehicleSummary without stopping the batch
includearray["recalls"]recalls, complaints, or both. Complaints are opt-in: one popular vehicle can carry hundreds (877 measured on a single 2022 model)
maxComplaintsPerVehicleint 1–2000100Newest complaints first; the cap keeps bills predictable. Discarded = never billed
complaintsFiledDaysBackint 1–3650Optional: only complaints filed in the last N days (by dateComplaintFiled). Discarded = never billed
maxResultsint 1–100001000Run-wide hard cap of written records

Rate etiquette: the NHTSA API publishes no numeric rate limit, so the Actor is deliberately polite — 2 concurrent requests with pacing and exponential backoff on 429/5xx, one request per vehicle per mode. A 200-vehicle recalls-only batch takes roughly 2–4 minutes. For bigger jobs, split across scheduled runs.

Output (missing = null / [], never invented)

Every record carries the same complete key set (single normalized contract); fields that don't apply to the record type are null. Real recall record (Honda Civic 2024 — official public data):

{
"recordType": "RECALL",
"vehicleIndex": 0,
"inputMake": "honda",
"inputModel": "civic",
"inputModelYear": 2024,
"make": "HONDA",
"model": "CIVIC",
"modelYear": "2024",
"manufacturer": "Honda (American Honda Motor Co.)",
"campaignNumber": "23V704000",
"component": "STEERING:RACK AND PINION",
"summary": "Honda (American Honda Motor Co.) is recalling certain 2022-2024 Civic...",
"consequence": "A damaged tire can fail and increase the risk of a crash or injury.",
"remedy": "Dealers will inspect and replace the electric power steering rack...",
"reportReceivedDate": "2023-10-19",
"reportReceivedDateRaw": "19/10/2023",
"parkIt": false,
"parkOutside": false,
"overTheAirUpdate": false,
"scrapedAt": "2026-07-30T12:00:00.000Z"
}
Field groupFieldsNotes
CorrelationrecordType, vehicleIndex, inputMake, inputModel, inputModelYearties every record back to your input list
Vehicle identitymake, model, modelYear, manufactureras returned by NHTSA
RecallcampaignNumber, actionNumber, component, summary, consequence, remedy, notes, reportReceivedDate (+Raw), parkIt, parkOutside, overTheAirUpdatecore fields¹: campaignNumber, component, summary, reportReceivedDate
ComplaintodiNumber, crash, fire, numberOfInjuries, numberOfDeaths, dateOfIncident (+Raw), dateComplaintFiled (+Raw), vin, components, componentsList[], products[], summarycore fields¹: odiNumber, dateComplaintFiled, components
MetascrapedAt, vinTruncatedBySource, vinMaskedByActor

¹ Core fields are watched by the built-in health check: if more than 50% come back null the run fails loudly naming the record type and dead field (DEAD_FIELDS) — never a silent broken dataset.

Dates — source formats preserved

The NHTSA recalls endpoint returns dates as DD/MM/YYYY and the complaints endpoint as MM/DD/YYYY (both verified against real records). The Actor emits clean ISO dates (reportReceivedDate, dateComplaintFiled, dateOfIncident) parsed with the correct per-endpoint format, and always keeps the original string in the matching *Raw field. An unparseable date is null — never guessed.

VIN privacy

NHTSA itself publishes complaint VINs truncated to 11 characters — the 6-character serial suffix that identifies the individual unit is removed at the source (100% of the measured sample). The Actor passes that value through unchanged and records vinTruncatedBySource: true. As a defensive privacy measure, if the API ever returns a longer VIN, the Actor masks everything beyond the 11-character descriptive prefix with * and sets vinMaskedByActor: true. The Actor never reconstructs or guesses serial numbers.

Run health

STATS (key-value store) records per-vehicle outcomes (vehicleSummary: OK, NO_RESULTS, INVALID_VEHICLE, FAILED, DUPLICATE_SKIPPED, SKIPPED_MAX_RESULTS), HTTP counters, retries, discard counters, vinTruncatedBySourceRate and per-type field completeness. ERRORS records failures with stable codes (INVALID_INPUT, INVALID_VEHICLE, HTTP_UNAVAILABLE, HTTP_TIMEOUT, HTTP_RATE_LIMITED, API_CONTRACT_CHANGED, DEAD_FIELDS, ALL_VEHICLES_FAILED).

  • A vehicle with zero recalls/complaints is a legitimate NO_RESULTS — flagged in STATS.legitimateNoResults, never a fake failure.
  • A batch where no vehicle completes fails loudly with ALL_VEHICLES_FAILED.
  • An invalid vehicle/year answers HTTP 400 at the source (verified) → controlled INVALID_VEHICLE for that entry only.

API usage examples

Run and get items in one call:

curl -s "https://api.apify.com/v2/acts/<YOUR_USERNAME>~nhtsa-vehicle-recalls-complaints/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST -H "Content-Type: application/json" \
-d '{"vehicles":[{"make":"honda","model":"civic","modelYear":2024}],"include":["recalls"]}'

Fleet recall audit on a weekly schedule (Console → Schedules):

{
"vehicles": [
{ "make": "ford", "model": "transit", "modelYear": 2022 },
{ "make": "ram", "model": "promaster", "modelYear": 2023 }
],
"include": ["recalls"]
}

Insurer signal feed — fresh complaints only:

{
"vehicles": [{ "make": "tesla", "model": "model 3", "modelYear": 2023 }],
"include": ["complaints"],
"complaintsFiledDaysBack": 90,
"maxComplaintsPerVehicle": 200
}

Fleet audits are a weekly habit. Use Apify's own Schedules, not a local scheduler — configure it once and it runs in the cloud whether or not your machine is on.

  1. Save your input as a Task (Console → this Actor → Create task), e.g. every model in your fleet with include: ["recalls"].
  2. Console → Schedules → Create schedule, add the Task, set the cron (e.g. Mondays 6am → 0 6 * * 1).
  3. Route the dataset to Slack, Sheets, your CRM or webhook via Apify integrations.

Recalls only grow over time, so a weekly audit catches new campaigns on vehicles you already own or list.

Pricing

Billed per record written to the dataset (Pay Per Event) — the Pricing tab on this page is always the authoritative source for current rates and for any per-run fee. Records discarded by caps or filters are never billed. Use include, maxComplaintsPerVehicle, complaintsFiledDaysBack and maxResults to control exactly what you pay for.

Honest limits

  • Lookup is by make + model + model year — not by VIN. (NHTSA's per-vehicle APIs are keyed that way; VIN decoding is a separate NHTSA service and out of scope for this version.)
  • Complaints volume varies wildly: 0 for some vehicles, hundreds for popular ones — that's why the per-vehicle cap defaults to 100 (newest first).
  • Recalls are the official historical record: they only grow; complaints reflect what owners filed with NHTSA, not verified defects.
  • No numeric rate limit is published by NHTSA; the Actor's pacing is deliberately conservative. Batches cap at 200 vehicles per run.
  • Data freshness follows the official recalls.gov / NHTSA ODI databases.

FAQ

Do I need an account or API key for NHTSA? No. The Actor reads the official public NHTSA APIs without logging in.

Why are VINs truncated? Because NHTSA publishes them that way. Complaint VINs arrive truncated to 11 characters at the source — the serial suffix that identifies an individual vehicle is already removed. The Actor passes that through unchanged and, as a defensive measure, masks anything longer. See "VIN privacy" above; the Actor never reconstructs or guesses serial numbers.

What exactly am I charged for? Per record written to the dataset (Pay Per Event) — everything discarded by caps or filters costs you nothing. The Pricing tab on this page is always the authoritative source for current rates and for any per-run fee.

Can I schedule it? Yes — that is the intended use. See "Schedule it" above.

Is this affiliated with NHTSA or the DOT? No. This is an unofficial community Actor, not affiliated with the National Highway Traffic Safety Administration or the U.S. Department of Transportation; all data comes from their official public APIs and remains subject to NHTSA's terms.