# NHTSA vehicle recalls + complaints by make/model/year (API) (`retrainmap/nhtsa-recalls-complaints`) Actor

Safety recalls and consumer complaints for any make / model / model year from NHTSA's public API (no key): campaign or ODI number, component, summary, consequence, remedy, manufacturer, dates, crash / fire / injury / death flags and the NHTSA page link - one normalised row per record.

- **URL**: https://apify.com/retrainmap/nhtsa-recalls-complaints.md
- **Developed by:** [RetrainMap Team](https://apify.com/retrainmap) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 records

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## NHTSA vehicle recalls + complaints by make/model/year (API)

One row per **safety recall campaign** and per **consumer complaint** for any make / model /
model year, read live from the National Highway Traffic Safety Administration's public vehicle
API — no key, no scraping. Give a list of vehicles (`{"make": "Toyota", "model": "Camry",
"year": 2020}`), choose recalls, complaints or both, and get the campaign or ODI number,
component, summary (trimmed to 3,000 characters), consequence and remedy (recalls),
manufacturer, report and incident dates, crash / fire / injury / death flags (complaints) and
the NHTSA page link — normalised, dates as `YYYY-MM-DD`.

**Complaints are unverified.** NHTSA publishes consumer complaints as received; neither NHTSA
nor this Actor verifies them. Recalls are the manufacturers' campaigns as filed with NHTSA.

### Data source and status

| | |
|---|---|
| Publisher | U.S. Department of Transportation, National Highway Traffic Safety Administration (NHTSA), Office of Defects Investigation |
| Site | https://www.nhtsa.gov/recalls |
| API read by this Actor | `https://api.nhtsa.gov/recalls/recallsByVehicle`, `https://api.nhtsa.gov/complaints/complaintsByVehicle` (plain GET, `make`, `model`, `modelYear`; the whole list in one response) and, only when a vehicle's recalls or complaints come back empty, `https://api.nhtsa.gov/products/vehicle/models` to log NHTSA's own model names for that side, make and year |
| Refresh cadence | NHTSA adds recalls as manufacturers file them and complaints as they are received (continuously; typically same-day). The Actor reads live on every run; `fetched_at` is the fetch time |
| Copyright | Works of the United States Government are not subject to copyright in the U.S. (17 U.S.C. §105). Please cite NHTSA as the source |
| Known caveats | Make and model must be NHTSA's spellings (case does not matter): `F-150`, not `F150`; `MODEL 3`, not `Model3`. **Recalls and complaints do not always share a model name**: for 2021 Ford, recalls are filed under `F-150` but complaints under body styles (`F-150 SUPER CREW`, `F-150 SUPER CAB`, `F-150 REGULAR CAB`, …), so one vehicle can return recalls and 0 complaints; when either side returns nothing, the run log lists NHTSA's model names for that side, so add those as extra vehicles. NHTSA sends recall dates day first and complaint dates month first; both are converted to `YYYY-MM-DD` (builds before 2026-09-11 wrote recall `report_date` as year-day-month, e.g. `2021-16-12`), and complaints' `12/31/1969` no-date placeholder is written as empty. A recall campaign covering several vehicles appears once per requested vehicle it covers. Complaint `vin_prefix` is the partial VIN NHTSA publishes. NHTSA has no per-complaint page, so complaint rows link to the vehicle page; recall rows link to the recall lookup page |

Identification: every request carries the User-Agent `RetrainMap data actor
info@steelyardclinical.com` and the contact address again in the standard `From:` header.
NHTSA publishes no rate limit; the Actor makes at most one request per 500 ms by default
(two requests per vehicle in `both` mode).

### Input

| Field | Type | Meaning |
|---|---|---|
| `mode` | `both` / `recalls` / `complaints` | Default `both` (recalls, then complaints, per vehicle) |
| `vehicles` | array of `{make, model, year}` | Required (the prefill lists three common vehicles) |
| `max_records` | integer | Default 500. Stop after this many rows in total, in vehicle order |
| `request_interval_ms` | integer | Default 500 (floor 250) |
| `contact_email` | string | Sent in the `From:` header |

Example — recalls only for two vehicles:

```json
{ "mode": "recalls",
  "vehicles": [ {"make": "Tesla", "model": "Model 3", "year": 2023},
                {"make": "Hyundai", "model": "Elantra", "year": 2022} ],
  "max_records": 200 }
```

### Output (dataset row)

`record_type` (`recall` / `complaint`), `make`, `model`, `year`, `nhtsa_id` (the campaign
number or ODI number), `campaign_number`, `odi_number`, `manufacturer`, `component`
(recalls: the component; complaints: the components as published, comma-separated),
`summary` (first 3,000 characters), `summary_truncated`, `consequence`, `remedy`, `notes`
(recalls), `report_date` (recall report received / complaint filed), `incident_date`
(complaints), `crash`, `fire`, `injuries`, `deaths` (complaints), `park_it`, `park_outside`,
`ota_update` (recalls), `vin_prefix` (complaints), `nhtsa_url`, `fetched_at`.

Fields that do not apply to a record type are `null`. A run summary (per-vehicle recall and
complaint counts, request count) is stored as `RUN_SUMMARY` in the run's key-value store.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `run-start` — once per run | $0.10 |
| `record` — per row written | $0.005 |

A 300-row pull costs $1.60. Rows stop when your run's maximum charge is reached; the run
summary says so.

### Operator

Steelyard Ventures LLC (RetrainMap) — info@steelyardclinical.com. The Actor writes only to its
own dataset and key-value store; it stores no credentials and sends nothing else.

# Actor input Schema

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

recalls = safety recall campaigns; complaints = consumer complaints filed with NHTSA's Office of Defects Investigation; both = recalls then complaints for each vehicle.

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

One object per vehicle: {"make": "Toyota", "model": "Camry", "year": 2020}. Make and model must be NHTSA's spellings (case does not matter, e.g. F-150, not F150); when a vehicle returns nothing the run log lists NHTSA's model names for that make and year.

## `max_records` (type: `integer`):

Stop after this many rows in total, in vehicle order (recalls before complaints for each vehicle). NHTSA returns every record of a vehicle in one request (no paging), so a popular model can have hundreds of complaints.

## `request_interval_ms` (type: `integer`):

Politeness delay towards api.nhtsa.gov, which publishes no rate limit. One request per vehicle and record type; the floor is 250 ms.

## `contact_email` (type: `string`):

Sent in the standard From: request header so the data owner can reach the operator (RFC 9110 s10.1.2).

## Actor input object example

```json
{
  "mode": "both",
  "vehicles": [
    {
      "make": "Toyota",
      "model": "Camry",
      "year": 2020
    },
    {
      "make": "Ford",
      "model": "F-150",
      "year": 2019
    },
    {
      "make": "Honda",
      "model": "Civic",
      "year": 2021
    }
  ],
  "max_records": 300,
  "request_interval_ms": 500,
  "contact_email": "info@steelyardclinical.com"
}
```

# Actor output Schema

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

Every recall and complaint as one row: type, vehicle, NHTSA number, component, summary, consequence, remedy, manufacturer, dates, incident flags, link.

## `results_csv` (type: `string`):

The same rows as a CSV file.

# 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": [
        {
            "make": "Toyota",
            "model": "Camry",
            "year": 2020
        },
        {
            "make": "Ford",
            "model": "F-150",
            "year": 2019
        },
        {
            "make": "Honda",
            "model": "Civic",
            "year": 2021
        }
    ],
    "max_records": 300
};

// Run the Actor and wait for it to finish
const run = await client.actor("retrainmap/nhtsa-recalls-complaints").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": [
        {
            "make": "Toyota",
            "model": "Camry",
            "year": 2020,
        },
        {
            "make": "Ford",
            "model": "F-150",
            "year": 2019,
        },
        {
            "make": "Honda",
            "model": "Civic",
            "year": 2021,
        },
    ],
    "max_records": 300,
}

# Run the Actor and wait for it to finish
run = client.actor("retrainmap/nhtsa-recalls-complaints").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": [
    {
      "make": "Toyota",
      "model": "Camry",
      "year": 2020
    },
    {
      "make": "Ford",
      "model": "F-150",
      "year": 2019
    },
    {
      "make": "Honda",
      "model": "Civic",
      "year": 2021
    }
  ],
  "max_records": 300
}' |
apify call retrainmap/nhtsa-recalls-complaints --silent --output-dataset

```

## MCP server setup

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

```

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/H51Zkcee0jtPDhpDR/builds/gNpc6EAiYU7UhkCd1/openapi.json
