# Vehicle Recall and Complaint Lookup (`comradecoding/vehicle-recall-lookup`) Actor

Look up US vehicle recalls and owner complaints by make, model and year or by VIN. Flat JSON rows, $0.0005 per row, failures free.

- **URL**: https://apify.com/comradecoding/vehicle-recall-lookup.md
- **Developed by:** [Comrade Coding](https://apify.com/comradecoding) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 recall or complaint rows

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

## Vehicle Recall and Complaint Lookup

Give it vehicles (make, model, model year) or VINs. It returns every US safety recall campaign on file for each vehicle, plus the owner complaints filed with the US federal vehicle safety agency, one flat row per recall or complaint.

The data comes from the agency's free public API (`api.nhtsa.gov` for recalls and complaints, `vpic.nhtsa.dot.gov` for decoding VINs). No login, no API key, no web page scraping.

This actor is not affiliated with or endorsed by any government agency or any vehicle manufacturer.

### What it does

1. Checks each input. Bad entries (a VIN with the wrong length, a vehicle with no year) are listed in the `FAILED_LOOKUPS` record and skipped.
2. For a VIN, asks the VIN decoder for its make, model and year.
3. Looks up the agency's own model names for that make and year. The recall endpoints only match exact names, so `crv` becomes `CR-V`, and a VIN decoded as `Silverado` series `1500` is matched to `SILVERADO 1500` and `SILVERADO LD 1500`. If a name matches more than three models, or none, the lookup fails with the list of names the agency uses for that year.
4. Fetches recalls and complaints for each matched model, drops duplicates, sorts complaints newest first, and keeps up to `maxComplaintsPerVehicle`.
5. Saves one row per recall or complaint until `maxItems` is reached.

### Input

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `vehicles` | array | one 2018 Honda Accord | Objects with `make`, `model`, `modelYear`, or strings like `2018, Honda, Accord`. Not case sensitive. |
| `vins` | array of strings | empty | Full 17-character VINs. |
| `includeRecalls` | boolean | `true` | One row per recall campaign. |
| `includeComplaints` | boolean | `true` | One row per owner complaint. |
| `maxComplaintsPerVehicle` | integer | `50` | Newest complaints kept per vehicle. `0` skips complaints. |
| `maxItems` | integer | `1000` | Stop after this many rows in total. Caps the cost of a run. |

Example:

```json
{
    "vehicles": [{ "make": "Honda", "model": "Accord", "modelYear": 2018 }, "2021, Tesla, Model 3"],
    "vins": ["1GCUYDED0KZ100000"],
    "maxComplaintsPerVehicle": 20,
    "maxItems": 200
}
```

### Output

A real recall row from a test run on 2026-10-28:

```json
{
    "source_url": "https://api.nhtsa.gov/recalls/recallsByVehicle?make=HONDA&model=ACCORD&modelYear=2018",
    "fetched_at": "2026-10-28T07:08:21.147Z",
    "record_type": "recall",
    "lookup_vin": null,
    "lookup_make": "HONDA",
    "lookup_model": "ACCORD",
    "lookup_model_year": 2018,
    "make": "HONDA",
    "model": "ACCORD",
    "model_year": 2018,
    "manufacturer": "Honda (American Honda Motor Co.)",
    "record_id": "20V314000",
    "date": "2020-05-28",
    "components": ["FUEL SYSTEM, GASOLINE:DELIVERY:FUEL PUMP"],
    "summary": "Honda (American Honda Motor Co.) is recalling certain 2018-2019 Acura NSX, 2019 Acura RDX, RLX and RLX Sport Hybrid, 2018-2019 Honda Accord, Civic Hatchback, Civic Type R and HR-V, 2019-2020 Insight and 2019 Fit vehicles.  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": "Honda will notify owners and dealers will replace the fuel pump assembly, free of charge.  The recall began July 22, 2020.  Owners may contact Honda customer service at 1-888-234-2138.",
    "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.",
    "park_it": false,
    "park_outside": false,
    "over_the_air_update": false,
    "incident_date": null,
    "crash": null,
    "fire": null,
    "injuries": null,
    "deaths": null,
    "complaint_vin": null
}
```

Every row has the same fields in the same order. Fields that belong to the other record type are `null`.

| Field | Recalls | Complaints |
| --- | --- | --- |
| `source_url` | API request the row came from | same |
| `fetched_at` | When the API answered (UTC) | same |
| `record_type` | `recall` | `complaint` |
| `lookup_vin`, `lookup_make`, `lookup_model`, `lookup_model_year` | What you asked for (after VIN decoding) | same |
| `make`, `model`, `model_year` | Vehicle as the agency lists it | same |
| `manufacturer` | Manufacturer name | same |
| `record_id` | Recall campaign number, such as `20V314000` | ODI complaint number |
| `date` | Date the agency received the recall report | Date the complaint was filed |
| `components` | The affected component, as one entry | List of components named |
| `summary` | Recall summary | The owner's complaint text |
| `consequence`, `remedy`, `notes` | Recall text | `null` |
| `park_it`, `park_outside`, `over_the_air_update` | Agency flags: do not drive, park outside, fixed by software update | `null` |
| `incident_date`, `crash`, `fire`, `injuries`, `deaths` | `null` | As reported in the complaint |
| `complaint_vin` | `null` | The partial VIN (first 11 characters) the API publishes |

Dates are `YYYY-MM-DD`. The API sends recall dates day first and complaint dates month first; both are converted. Text fields over 20,000 characters are cut and marked.

Two records go to the run's key-value store, not the dataset, so they are never charged:

- `SUMMARY`: counts per run and per lookup, the agency model names used, how a VIN decoded, complaints left out by the per-vehicle cap, API requests and retries, and `stopped_by` (`done`, `maxItems` or `charge limit`).
- `FAILED_LOOKUPS`: each input that failed, with the reason. A lookup where recalls worked but complaints failed is listed with `"partial": true` and its recall rows are still saved.

### Limits

- **A VIN lookup is not a check of one vehicle's repair status.** The public API has no recall-by-VIN endpoint. The actor decodes the VIN to make, model and year and returns every recall for that vehicle line. Whether a specific car is affected or already repaired is on the manufacturer's or the agency's own VIN search page.
- US vehicles only. Recalls and complaints filed with the US agency, as the API returns them, with the same delay the agency has in publishing them.
- Vehicles only. Tires, child seats and equipment recalls are not looked up.
- A vehicle with no recalls or complaints gives no rows and is not charged. It is listed in `SUMMARY` with zero counts.
- Complaint text is written by the public and passed through exactly as the API returns it. The actor adds nothing to it and does no enrichment. The API itself publishes only a partial VIN for complaints.
- Requests are sent one at a time with 0.5 to 1 s between requests to each API host. HTTP 429 and 5xx answers, timeouts and network errors are retried up to 3 times with backoff (2, 4, 8 s, or the API's `Retry-After` up to 60 s). `robots.txt` of each host is read once and respected.
- Each lookup makes 3 to 5 requests, so plan on about 4 seconds per vehicle.

### Pricing

Pay per result: **$0.50 per 1,000 rows** ($0.0005 per recall or complaint row). Failed lookups, vehicles with no records, and the `SUMMARY` and `FAILED_LOOKUPS` records are free.

Typical runs:

| Run | Rows | Cost |
| --- | --- | --- |
| One vehicle, recalls plus 50 newest complaints | about 55 | about $0.03 |
| 20 vehicles with the defaults (stops at the default `maxItems` of 1,000) | up to 1,000 | up to $0.50 |
| 500 fleet VINs, recalls only | about 5,000 (about 10 recalls each) | about $2.50 |

The default `maxItems` of 1,000 caps a run at $0.50. Raise it for big lists. Apify's per-run cost limit also stops the run when reached.

### Use it from an AI agent

Add this actor as a tool through Apify's MCP server: `https://mcp.apify.com?tools=comradecoding/vehicle-recall-lookup`. The agent gets flat JSON rows of US recalls and owner complaints for a make, model and year or a VIN.

### Integrations

Anything that can call the Apify API can run this actor: the Apify API and client libraries, and Apify's integrations for Make, n8n, Zapier and LangChain. Results come back as a dataset you can download as JSON, CSV or Excel.

### FAQ

**Does a VIN lookup tell me if my car was repaired?**

No. The public API has no recall-by-VIN endpoint, so the VIN is decoded to make, model and year and every recall for that vehicle line is returned. Check one car's repair status on the manufacturer's or the agency's own VIN search.

**Which countries are covered?**

US vehicles only, as filed with the US agency.

**Am I charged for a vehicle with no recalls?**

No. It gives no rows and is listed in SUMMARY with zero counts.

### Related actors by ComradeCoding

- [URL to Markdown Converter](https://apify.com/comradecoding/url-to-markdown)
- [Sitemap URL Extractor](https://apify.com/comradecoding/sitemap-url-extractor)
- [PDF to Text and JSON](https://apify.com/comradecoding/pdf-to-text)

# Actor input Schema

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

Vehicles to look up. Each entry is an object with make, model and modelYear, or a string in the form year, make, model (for example 2018, Honda, Accord). Names are not case sensitive. If a model name is close but not exact (for example Silverado for SILVERADO 1500), the actor uses the agency's matching names. Entries that fail are listed in the FAILED_LOOKUPS record and are not charged.

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

Full 17-character VINs. Each VIN is decoded to its make, model and year, then looked up like a vehicle above. The result covers every recall for that make, model and year, not whether this one vehicle has been repaired.

## `includeRecalls` (type: `boolean`):

Return one row per safety recall campaign for each vehicle.

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

Return owner complaints filed with the agency for each vehicle, newest first. Complaint text is passed through as the public API returns it.

## `maxComplaintsPerVehicle` (type: `integer`):

Keep at most this many complaints for each vehicle, newest first. Popular models can have thousands. Set 0 to skip complaints.

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

Stop after this many rows (recalls plus complaints) have been saved across all vehicles. You pay per row, so this caps the cost of a run.

## Actor input object example

```json
{
  "vehicles": [
    {
      "make": "Honda",
      "model": "Accord",
      "modelYear": 2018
    },
    "2021, Tesla, Model 3"
  ],
  "vins": [
    "1HGCV1F17JA000000"
  ],
  "includeRecalls": true,
  "includeComplaints": true,
  "maxComplaintsPerVehicle": 20,
  "maxItems": 200
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

## `failures` (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": [
        {
            "make": "Honda",
            "model": "Accord",
            "modelYear": 2018
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("comradecoding/vehicle-recall-lookup").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": [{
            "make": "Honda",
            "model": "Accord",
            "modelYear": 2018,
        }] }

# Run the Actor and wait for it to finish
run = client.actor("comradecoding/vehicle-recall-lookup").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": [
    {
      "make": "Honda",
      "model": "Accord",
      "modelYear": 2018
    }
  ]
}' |
apify call comradecoding/vehicle-recall-lookup --silent --output-dataset

```

## MCP server setup

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

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/rtlIDofPsxwQF2zY3/builds/l4oaqVpkcq8E5oxic/openapi.json
