# NHTSA Vehicle Recalls & Complaints Scraper - Car Recall API (`deanko/nhtsa-scraper`) Actor

NHTSA car recalls & owner complaints by make, model, year, whole make or campaign number. Remedy, crashes, fires, injuries. Official data, no API key.

- **URL**: https://apify.com/deanko/nhtsa-scraper.md
- **Developed by:** [dean ko](https://apify.com/deanko) (community)
- **Categories:** Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## NHTSA Vehicle Recalls & Complaints Scraper - Car Recall API

Get official **NHTSA vehicle recalls** and **owner complaints** for any car, truck, SUV or motorcycle sold in the US, as clean flat rows you can open in Excel or load into a database. Search by **year, make and model**, pull **every model of a make across a range of years**, or look up **recall campaigns by number**. It works like a **car recall API** you can call from your code or run on a schedule.

All data comes from the free, official NHTSA API (`api.nhtsa.gov`, US Department of Transportation). No API key, no proxies, no browser, so runs are fast and cheap.

### What does the NHTSA Recalls & Complaints Scraper do?

For every vehicle you give it, the Actor returns:

- **Safety recalls**: campaign number with a link to nhtsa.gov, report date, manufacturer, component, defect summary, consequence, remedy, notes, "park it" and "park outside" warnings, and the over-the-air (OTA) remedy flag.
- **Owner complaints (defect reports)**: ODI number, date filed, date of incident, components, the owner's own description, crash and fire flags, number of injuries and deaths, and the truncated VIN prefix NHTSA publishes.

Recalls and complaints share one table, and a `type` column tells them apart.

#### Who is it for?

- **Used-car dealers and marketplaces**: check vehicles in stock for recall campaigns and common defects before you list them.
- **Insurers, warranty and extended-service companies**: score models by complaint volume, component, crashes, fires and injuries.
- **Fleet managers**: run your fleet list on a schedule and catch new recalls for the vehicles you operate.
- **Lawyers and consumer advocates**: build defect datasets for one make across many model years in minutes.
- **Journalists, researchers and data teams**: find the most-complained-about components for a model year and quote owners' own descriptions.
- **Developers and AI agents**: get NHTSA recall and complaint data as JSON through the Apify API, without handling NHTSA's quirks yourself.

### Why use this Actor?

- **Recalls and complaints in one run, in one table.** Choose `recalls`, `complaints` or `both`.
- **Whole-make expansion.** Enter `Tesla` and a year range, and the Actor finds every model NHTSA lists for each year and pulls all of them. Most NHTSA tools need one make, model and year at a time.
- **Handles body-style variants.** NHTSA sometimes files a vehicle only under variants such as `F-150 SUPER CREW` or `F-150 REGULAR CAB`. If the exact model returns nothing, the Actor checks those variants for you.
- **One row per recall campaign.** Campaign-number lookups merge NHTSA's per-vehicle records into a single row with an `affectedVehicles` list.
- **No duplicate complaints.** A complaint filed against several model variants is returned only once.
- **Newest complaints first.** A small `maxItems` gives you the latest complaints for each vehicle.
- **Full text.** Summaries, consequences and remedies are returned in full, not cut short.
- **Privacy-safe.** NHTSA publishes no complainant names or contact details, and the Actor collects none. VINs are only the truncated prefix NHTSA itself publishes.
- **Cost control.** You pay per row, `maxItems` caps the row count, and the Actor stops as soon as your maximum charge per run is reached.

### How to use it

1. Click **Try for free** (or **Start**) on this page.
2. Under **What to collect**, choose `Recalls`, `Complaints` or `Recalls + complaints`.
3. Add **Vehicles**, for example `2020 Toyota Camry`, or `{"make": "Ford", "model": "F-150", "modelYear": 2021}`.
4. Optional: add makes under **All models of these makes** and set **Year from** and **Year to**.
5. Optional: add **Recall campaign numbers** such as `20V682000`.
6. Set **Max results** and click **Start**.
7. Download the results as JSON, CSV, Excel or HTML, or read them through the API.

The default input (`2020 Toyota Camry`, both types, 20 rows) finishes in a few seconds and costs about $0.02.

#### Input example

```json
{
  "mode": "both",
  "vehicles": [
    "2020 Toyota Camry",
    { "make": "Tesla", "model": "Model 3", "modelYear": 2022 }
  ],
  "allModelsOfMake": ["Rivian"],
  "yearFrom": 2022,
  "yearTo": 2024,
  "campaignNumbers": ["20V682000"],
  "maxItems": 500
}
```

| Field | Type | Description |
|---|---|---|
| `mode` | string | `recalls`, `complaints` or `both`. Default: `both`. |
| `vehicles` | array | `"2020 Toyota Camry"` strings or `{"make", "model", "modelYear"}` objects. |
| `allModelsOfMake` | array | Makes to expand into every model NHTSA lists, e.g. `Tesla`. |
| `yearFrom` / `yearTo` | integer | Model year range for `allModelsOfMake`. If empty, the current year is used. |
| `campaignNumbers` | array | NHTSA recall campaign numbers, e.g. `20V682000`. |
| `maxItems` | integer | Maximum number of rows, recalls and complaints combined. Default: 20. |

### Output

#### Recall row

```json
{
  "type": "recall",
  "id": "20V682000",
  "url": "https://www.nhtsa.gov/recalls?nhtsaId=20V682000",
  "date": "2020-04-11",
  "manufacturer": "Toyota Motor Engineering & Manufacturing",
  "component": "FUEL SYSTEM, GASOLINE:DELIVERY:FUEL PUMP",
  "summary": "Toyota Motor Engineering & Manufacturing (Toyota) is recalling certain ... The low-pressure fuel pump inside the fuel tank may fail.",
  "consequence": "If the fuel pump fails, the engine can stall while driving, increasing the risk of a crash.",
  "remedy": "Toyota will notify owners, and dealers will replace the fuel pump assembly with an improved one, free of charge. ...",
  "notes": "Owners may also contact the National Highway Traffic Safety Administration Vehicle Safety Hotline ...",
  "potentialUnitsAffected": null,
  "parkIt": false,
  "parkOutside": false,
  "overTheAirUpdate": false,
  "modelYear": "2020",
  "make": "TOYOTA",
  "model": "CAMRY",
  "scrapedAt": "2026-10-19T08:23:00.537Z"
}
```

#### Complaint row

```json
{
  "type": "complaint",
  "id": "11770517",
  "date": "2026-10-12",
  "dateOfIncident": "2026-10-05",
  "modelYear": "2020",
  "make": "TOYOTA",
  "model": "CAMRY",
  "manufacturer": "Toyota Motor Corporation",
  "component": "ELECTRICAL SYSTEM,AIR BAGS,UNKNOWN OR OTHER",
  "summary": "The \"airbag malfunction\" light keeps coming on and off ...",
  "crash": false,
  "fire": false,
  "numberOfInjuries": 0,
  "numberOfDeaths": 0,
  "vinPrefix": "4T1C11AK2LU",
  "scrapedAt": "2026-10-19T08:23:00.537Z"
}
```

#### Output fields

| Field | Recall | Complaint | Description |
|---|:-:|:-:|---|
| `type` | yes | yes | `recall` or `complaint` |
| `id` | yes | yes | NHTSA campaign number (recall) or ODI number (complaint) |
| `url` | yes | | Link to the recall on nhtsa.gov |
| `date` | yes | yes | Recall report date or complaint filing date (YYYY-MM-DD) |
| `dateOfIncident` | | yes | Date of the incident the owner reported |
| `modelYear`, `make`, `model` | yes | yes | Vehicle |
| `manufacturer` | yes | yes | Manufacturer name as filed with NHTSA |
| `component` | yes | yes | Affected component or components |
| `summary` | yes | yes | Defect summary (recall) or owner's description (complaint) |
| `consequence`, `remedy`, `notes` | yes | | Safety risk, the fix, and extra notes |
| `potentialUnitsAffected` | yes | | Number of vehicles affected, when NHTSA provides it |
| `parkIt`, `parkOutside` | yes | | NHTSA "do not drive" and "park outside" warnings |
| `overTheAirUpdate` | yes | | `true` if the remedy is an OTA software update |
| `affectedVehicles` | campaign lookups | | Every year, make and model in the campaign |
| `crash`, `fire` | | yes | Whether the owner reported a crash or fire |
| `numberOfInjuries`, `numberOfDeaths` | | yes | Injuries and deaths reported |
| `vinPrefix` | | yes | Truncated VIN as published by NHTSA (no serial number) |
| `scrapedAt` | yes | yes | When the row was collected |

The **Overview** table view in the Console shows the key columns at a glance.

### Pricing

This Actor uses **pay per event** pricing:

- **$0.001 per result**, which is **$1 per 1,000 rows**.
- A tiny Actor start fee of $0.00005 per GB of memory.

**Example:** you check 40 vehicles in your inventory for recalls only and get 120 recall rows. You pay 120 x $0.001 = **$0.12**, plus a fraction of a cent for the start. The default input (20 rows) costs about **$0.02**.

You only pay for rows you receive. Set **Max results** or a maximum charge per run, and the Actor stops when it reaches either one. On the Apify free plan, the monthly free credit covers thousands of rows.

### Integrations and API

Use the Actor from your own code with the Apify API client. It returns the same JSON shown above.

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("deanko/nhtsa-scraper").call(run_input={
    "mode": "recalls",
    "vehicles": ["2020 Toyota Camry", "2021 Ford F-150"],
    "maxItems": 100,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["id"], row["component"], row["remedy"])
```

**JavaScript / Node.js**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('deanko/nhtsa-scraper').call({
    mode: 'complaints',
    vehicles: [{ make: 'Tesla', model: 'Model 3', modelYear: 2022 }],
    maxItems: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((c) => c.crash || c.fire));
```

You can also:

- Run it on a **Schedule** (for example daily for your fleet) and get alerts through **Webhooks**, Slack or email.
- Connect it to **Zapier, Make, n8n, Google Sheets, Airbyte** and other Apify integrations.
- Call it from AI agents through the **Apify MCP server**.

### FAQ

**Where does the data come from?**
From the official NHTSA public API at `api.nhtsa.gov` (recalls by vehicle, recalls by campaign number, complaints by vehicle, and the model list). This is the same data shown on nhtsa.gov/recalls. The Actor doesn't scrape web pages.

**Do I need an NHTSA API key?**
No. The NHTSA API is free and needs no key or account.

**Are there rate limits?**
NHTSA doesn't publish a fixed rate limit for its API, but it may slow down or reject heavy automated traffic. The Actor sends requests one at a time with a short pause between vehicles, and retries server errors with backoff. Very large jobs, such as several whole makes over many years, take longer for this reason.

**Can I look up a recall by VIN?**
Not yet. The Actor searches by year, make and model, or by campaign number. A recall for a model doesn't always apply to every VIN of that model. To confirm a specific vehicle, use the official VIN lookup at nhtsa.gov/recalls.

**Why did my vehicle return nothing?**
Check the spelling against NHTSA's names, for example `CR-V`, `MODEL 3` or `F-150`. For multi-word makes, use the object form: `{"make": "Land Rover", "model": "Range Rover", "modelYear": 2019}`. The run log shows a warning for any vehicle it couldn't parse.

**Do complaints mean the vehicle is defective?**
No. Complaints are reports filed by owners. NHTSA doesn't verify them, and they don't prove a defect, a cause or a recall. Use them as signals, together with recalls and NHTSA investigations.

**How fresh is the data?**
Every run queries NHTSA live, so you get whatever NHTSA publishes at that moment.

**Is there personal data?**
NHTSA doesn't publish complainant names or contact details, and the Actor collects none. The VIN field is only the truncated prefix NHTSA already makes public.

### Limitations

- US vehicles only. NHTSA covers vehicles and equipment sold in the United States.
- No VIN-level recall check. Results are per year, make and model, or per campaign number.
- Tires, child seats and standalone equipment recalls aren't covered. The Actor uses the vehicle endpoints.
- `potentialUnitsAffected` is often empty in vehicle lookups. Campaign-number lookups fill it more often.
- Complaint text is free text written by owners, published as-is by NHTSA.
- With `allModelsOfMake`, a big make over many years can mean hundreds of vehicles, so the run takes longer. Use `maxItems` to cap cost.

### Support and feedback

Found a bug, need a field, or want VIN lookups or another NHTSA dataset? Open an issue on the **Issues** tab of this Actor. Requests are read and answered there.

Data comes from the public NHTSA API (US Department of Transportation). This Actor isn't affiliated with or endorsed by NHTSA. You are responsible for using the data in line with the laws that apply to you.

# Actor input Schema

## `mode` (type: `string`):

Collect official NHTSA safety recalls, owner complaints, or both for every vehicle. Campaign number lookups always return recalls.

## `vehicles` (type: `array`):

Vehicles to look up, one per entry. Either a string with year, make and model, e.g. "2020 Toyota Camry" or "2021 Ford F-150", or an object {"make": "Land Rover", "model": "Range Rover", "modelYear": 2019}. Use the object form for multi-word makes. Model names follow NHTSA spelling (CR-V, MODEL 3, F-150); body-style variants such as F-150 SUPER CREW are checked automatically.

## `allModelsOfMake` (type: `array`):

Optional. Expand each make into every model NHTSA lists for each model year in 'Year from' to 'Year to', e.g. Tesla, Rivian, Honda. A big make over many years can produce thousands of rows, so set Max results accordingly.

## `yearFrom` (type: `integer`):

First model year used with 'All models of these makes'. Defaults to the current year when empty.

## `yearTo` (type: `integer`):

Last model year used with 'All models of these makes'. Defaults to 'Year from' when empty.

## `campaignNumbers` (type: `array`):

Optional. NHTSA recall campaign numbers to look up directly, e.g. 20V682000 or 24V051000. Returns one row per campaign with the full list of affected vehicles (affectedVehicles).

## `maxItems` (type: `integer`):

Stop after this many rows (recalls + complaints combined). You pay per row, so this is also your cost cap: 20 rows = $0.03. Complaints are returned newest first.

## Actor input object example

```json
{
  "mode": "both",
  "vehicles": [
    "2020 Toyota Camry"
  ],
  "allModelsOfMake": [],
  "campaignNumbers": [],
  "maxItems": 20
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "both",
    "vehicles": [
        "2020 Toyota Camry"
    ],
    "allModelsOfMake": [],
    "campaignNumbers": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("deanko/nhtsa-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "both",
    "vehicles": ["2020 Toyota Camry"],
    "allModelsOfMake": [],
    "campaignNumbers": [],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("deanko/nhtsa-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "both",
  "vehicles": [
    "2020 Toyota Camry"
  ],
  "allModelsOfMake": [],
  "campaignNumbers": [],
  "maxItems": 20
}' |
apify call deanko/nhtsa-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deanko/nhtsa-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/I5krd1XjT2T4LveV9/builds/xAhVs5WsgJchaHTxF/openapi.json
