# Vehicle Safety & Reliability Intelligence (NHTSA) (`sashaebashu/nhtsa-vehicle-intel`) Actor

Recalls, owner complaints and crash-test ratings for any vehicle or VIN — with severity scoring, complaint trends and alerts when a new recall or do-not-drive order appears.

- **URL**: https://apify.com/sashaebashu/nhtsa-vehicle-intel.md
- **Developed by:** [Sasha Ebashu](https://apify.com/sashaebashu) (community)
- **Categories:** Automation, E-commerce, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.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/platform/actors/running/actors-in-store#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

## Vehicle Safety & Reliability Intelligence (NHTSA)

Give it a **VIN**, a year/make/model, or a whole marque — get back everything the U.S. safety
regulator knows about that vehicle, scored and ready to act on: **recalls**, **owner complaints**
and **crash-test ratings**, in one row per vehicle.

Built on NHTSA's public APIs. No key, no login, no scraping of a site that might block you.

### What makes this more than a data dump

- **Do-not-drive alerts surfaced.** NHTSA flags its most severe recalls as *Park It* (stop driving
  now) and *Park Outside* (fire risk — don't park in a garage). Those become top-level
  `hasParkItRecall` / `hasParkOutsideRecall` fields instead of being buried in campaign text.
- **A severity score, not a complaint count.** 400 complaints about a squeaky trim panel is not
  400 complaints about stalling in traffic. Each complaint is weighted:
  `1 base + 3 if crash + 5 if fire + 10 per injury + 100 per death`. The formula is published here
  on purpose — you can defend the number to a client or recompute it yourself.
- **Trend, not just history.** `complaintsLast30d`, `Last90d` and `Last365d` show whether a problem
  is *emerging*. A spike here typically precedes a recall, which is the whole point of watching.
- **The failing parts, ranked.** `topComponents` — for a 2020 Camry: electrical 39, air bags 36,
  engine 21.
- **VIN in, intelligence out.** Paste the VINs you already have; they are decoded to year/make/model
  for you, 50 per request, and the body style, engine and plant come along for free.

### Monitor mode

Run it on a schedule and each vehicle is labelled against the previous run:

| `changeType` | Means |
|---|---|
| **`park_it_recall`** | A do-not-drive recall just appeared — the alert that matters most |
| `new_recall` | A new recall campaign was published (listed in `newRecallCampaigns`) |
| `rating_change` | The crash-test star rating moved |
| `complaint_spike` | More owner complaints than last run |
| `new` | First time seen in this scope |
| `unchanged` | Nothing moved |

`park_it_recall` is checked **before** everything else, because a human reading the output needs to
see that first. Turn on **Output only changed vehicles** to get a pure alert feed.

### Input

Mix and match — all three are optional and can be combined:

| Field | What it does |
|---|---|
| **VINs** | A fleet list. Decoded automatically; undecodable VINs are reported and skipped. |
| **Vehicles** | `{"modelYear": 2020, "make": "Toyota", "model": "Camry"}`. |
| **Whole makes** + **Model years** | Every model of a make for those years. Leave the years empty and the Actor picks the newest year NHTSA actually answers for — the current model year is listed in their catalogue before the data exists, so asking for it returns nothing. |
| **Include owner complaints** | The reliability signal, and the heaviest call. Off = fast recalls-and-ratings pass. |
| **Include crash-test ratings** | Stars, rollover, driver-assist equipment, crash photo/video. Two extra requests per vehicle. |
| **Monitor mode / Output only changed** | The alert behaviour above. |

### Notes & limits

Properties of the source, measured rather than assumed:

- **Investigations are not available.** NHTSA publishes no public investigations endpoint — the URL
  that looks like one answers `403 Missing Authentication Token`. The crash-rating record does carry
  an `InvestigationCount`, but the underlying cases cannot be fetched, so this Actor does not pretend
  to have them.
- **Complaints cannot be filtered by date at the source.** `startDate`, `fromDate` and
  `dateComplaintFiled` were each tested and all return the identical count, so every run pulls the
  full complaint history and the trend windows are computed locally. That is why complaints are the
  expensive part of a large monitoring job.
- **VINs decode 50 at a time.** A batch of 60 comes back with zero results, so requests are chunked
  at 50.
- **A model year can have several rated body styles.** Each has its own stars; the Actor reports the
  first and tells you how many exist in `ratedVariantsAvailable`, rather than silently picking one.
- **Body styles are collapsed to one row per vehicle.** NHTSA lists a pickup once per cab and fuel
  type — `F-150 (REGULAR CAB) GAS`, `(SUPER CAB) GAS`, `(SUPER CREW) GAS` — and returns the *same*
  complaints for each. Left alone, one truck fills three rows with identical numbers and anyone
  summing the make triples its count, so they are merged and the source names listed in
  `complaintModelVariants`. **Different powertrains stay separate**: `F-150`, `F-150 LIGHTNING BEV`
  and `F-150 HEV` are three vehicles, not one, and their complaints are never mixed.
- **A clean vehicle gets a row, not silence.** No recalls and no complaints is an answer — it is
  what "is this one safe?" is asking — so it comes back with `hasKnownIssues: false`. It also means
  monitor mode holds a baseline for that vehicle, so its first recall later arrives as
  `new_recall` rather than as a brand-new row.
- **Whole-make expansion reads both of NHTSA's model lists.** The catalogue is split by issue type:
  one list of models with recalls, another of models with complaints. Both are merged, so a car
  people complain about but that was never recalled — the one an early-warning tool exists to
  find — is not missed.
- **Make and model spelling must match NHTSA's catalogue.** An unknown name answers HTTP 400 (not an
  empty result), and is reported as a warning instead of becoming an empty row.
- **The API is public and effectively unthrottled** — 11 of 12 rapid calls succeeded and the one
  miss retried clean — so failures are treated as transient and retried, never as "no data".
- The Actor honours your **Maximum cost per run** and stops when the cap is reached.

# Actor input Schema

## `vins` (type: `array`):

Vehicle Identification Numbers. Each is decoded to year/make/model automatically, so you can paste a fleet list straight from your own records. Decoded 50 at a time.

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

Look vehicles up directly, e.g. {"modelYear": 2020, "make": "Toyota", "model": "Camry"}. Spelling must match NHTSA's own catalogue.

## `makes` (type: `array`):

Every model of these makes, for the model years below. One make-year can expand to dozens of models (Ford 2024 = 66), so watch the result count.

## `modelYears` (type: `array`):

Which model years to expand the makes above into. Leave empty and the Actor picks the newest year NHTSA actually has data for — the current model year is usually listed but not yet queryable.

## `includeComplaints` (type: `boolean`):

Owner-filed complaints with severity scoring and 30/90/365-day trends. This is the reliability signal, and the heaviest call — a popular model returns a few hundred complaints. Turn off for a fast recalls-and-ratings pass.

## `includeRatings` (type: `boolean`):

NHTSA 5-star crash ratings, rollover probability, driver-assist equipment and crash-test photo/video links. Costs two extra requests per vehicle.

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

Overall cap on vehicles returned. 0 = no cap.

## `maxConcurrency` (type: `integer`):

Vehicles looked up in parallel.

## `monitorMode` (type: `boolean`):

Compare against the previous run over the same input and label every vehicle: park\_it\_recall, new\_recall, rating\_change, complaint\_spike, new, unchanged. Adds the list of recall campaigns that appeared since last time.

## `onlyChanges` (type: `boolean`):

Monitor mode only — return just the vehicles that moved.

## Actor input object example

```json
{
  "vins": [
    "1HGCM82633A004352",
    "1FTFW1ET5DFC10312"
  ],
  "vehicles": [
    {
      "modelYear": 2020,
      "make": "Toyota",
      "model": "Camry"
    }
  ],
  "makes": [
    "Ford"
  ],
  "modelYears": [
    "2024",
    "2025"
  ],
  "includeComplaints": true,
  "includeRatings": true,
  "maxItems": 0,
  "maxConcurrency": 5,
  "monitorMode": false,
  "onlyChanges": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `alerts` (type: `string`):

No description

## `safety` (type: `string`):

No description

## `full` (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 = {
    "vehicles": [
        {
            "modelYear": 2020,
            "make": "Toyota",
            "model": "Camry"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sashaebashu/nhtsa-vehicle-intel").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 = { "vehicles": [{
            "modelYear": 2020,
            "make": "Toyota",
            "model": "Camry",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("sashaebashu/nhtsa-vehicle-intel").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 '{
  "vehicles": [
    {
      "modelYear": 2020,
      "make": "Toyota",
      "model": "Camry"
    }
  ]
}' |
apify call sashaebashu/nhtsa-vehicle-intel --silent --output-dataset

```

## MCP server setup

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

```

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/xkZVaZ0REvidqeFBh/builds/yoIjKlpQJ1jiSNWgc/openapi.json
