# Copart Salvage Auctions + NHTSA VIN Specs (`radar-scraper/copart-scraper`) Actor

Scrape Copart salvage and clean-title auction lots by make, model or keyword. Get current bids, auction dates, damage, title type, images and NHTSA vehicle specs, plus an estimated margin when Copart publishes value and repair estimates. Incremental mode returns only new lots. $5 per 1,000 lots.

- **URL**: https://apify.com/radar-scraper/copart-scraper.md
- **Developed by:** [Juan Felipe Henao López](https://apify.com/radar-scraper) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 lot scrapeds

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

## Copart Salvage Auctions + NHTSA VIN Specs

Scrape **Copart** salvage and clean-title auction lots by make, model or keyword. Each lot comes with the current bid, auction date, damage, title type, thumbnail image and **official NHTSA vehicle specs** (engine, drive type, body class, plant), plus an estimated margin when Copart publishes its value and repair estimates.

**Incremental mode** returns only lots you have not received before, so you can run it daily and get a clean feed of new inventory. **Price: $5 per 1,000 lots.**

***

### Who is it for?

- **Salvage car importers** buying US vehicles for Latin America, the Middle East and Africa.
- **Rebuilders and repair shops** sourcing repairable vehicles.
- **Used-car dealers and resellers** tracking inventory and prices.
- **Automotive data analysts** studying auction supply and prices by model.

### What you can do with it

1. **A daily feed of new lots for the makes you buy.** Schedule the Actor with `incrementalMode: true` (for example `query: "toyota rav4"`) and send the new lots to a Google Sheet, Slack, your CRM or WhatsApp through **n8n**, **Make** or the Apify API.
2. **Find "Run and Drive" vehicles with a high estimated margin.** Turn on `onlyArbitrageDeals` (runs and drives, bid ≤ 35% of value, estimated margin ≥ $1,500), or filter `conditionGrade = RUN_AND_DRIVE` yourself and sort by `estimatedGrossMarginUSD`.
3. **Price research by model.** Pull a few thousand lots of one model and compare current bids, damage, title type and Copart's value estimates.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `query` | string | `ford` | Make, model or keyword. Every word must match (`toyota rav4` returns only Toyota RAV4 lots), and lots Copart returns that do not match are dropped and not charged. Spellings are normalized: `F-150`, `F150` and `F 150` (or `RAV4`, `RAV-4`, `RAV 4`; `CR-V`, `CRV`) work the same. |
| `maxItems` | integer | `30` | Maximum lots to return and charge (up to 5,000; about 4–6 minutes per 1,000 lots). |
| `enrichWithNHTSA` | boolean | `true` | Decode each VIN with the US DOT NHTSA vPIC API. |
| `onlyArbitrageDeals` | boolean | `false` | Return only lots flagged `isArbitrageOpportunity` (strict definition below; about 6–8% of lots). The Actor reviews up to 25 × Max Items lots to find them. |
| `incrementalMode` | boolean | `false` | Skip lots delivered by a previous run of the same search: they are not returned and **not charged**. |
| `stateKey` | string | — | Optional name for the incremental history (to share it across searches). |
| `resetIncrementalState` | boolean | `false` | Delete the incremental history and start over. |
| `portals` | array | `["COPART"]` | `IAAI` is **experimental** (see Limitations). |

### Output

One item per lot. A real example (run of 2026-10-19):

```json
{
  "id": "copart-71291356",
  "portal": "COPART",
  "lotNumber": "71291356",
  "title": "2026 FORD MAVERICK XLT",
  "year": 2026,
  "make": "FORD",
  "model": "MAVERICK",
  "vin": "3FTTW8JA7TR******",
  "currentBidUSD": 7700,
  "buyItNowPriceUSD": null,
  "estimatedRetailValueUSD": 34053,
  "estimatedRepairCostUSD": 21707,
  "odometerMiles": 784,
  "primaryDamage": "REAR END",
  "yardName": "WI - MILWAUKEE SOUTH",
  "yardCity": "FRANKLIN",
  "yardState": "WI",
  "hasNoBidsYet": false,
  "bidToRetailRatioPct": 22.6,
  "estimatedGrossMarginUSD": 4646,
  "conditionGrade": "RUN_AND_DRIVE",
  "titleTypeNormalized": "SALVAGE_TITLE",
  "titleTypeRaw": "CERT OF TITLE-CLAIM PAID",
  "isArbitrageOpportunity": true,
  "nhtsaSpecs": {
    "make": "FORD",
    "model": "Maverick",
    "modelYear": "2026",
    "bodyClass": "Pickup",
    "driveType": "AWD/All-Wheel Drive",
    "engineCylinders": "4",
    "displacementL": "2",
    "fuelTypePrimary": "Gasoline",
    "vehicleType": "TRUCK",
    "plantCountry": "MEXICO",
    "plantCity": "HERMOSILLO"
  },
  "auctionDate": "2026-10-19T17:00:00.000Z",
  "images": ["https://cs.copart.com/v1/AUTH_svc.pdoc00001/lpp/1026/819bdccd34c44e2f93c17e1b0133f59a_thb.jpg"],
  "url": "https://www.copart.com/lot/71291356",
  "scrapedAt": "2026-10-19T17:23:09.748Z"
}
```

#### How the derived fields are calculated

- `estimatedRetailValueUSD` and `estimatedRepairCostUSD` are **Copart's own estimates**. When Copart does not publish one, the field is `null` (measured on 500 Ford lots in the cloud, 2026-10-20: **value estimate in 97%** of lots, **repair estimate in 44%**; the repair estimate varies by model, between 20% and 69% in our samples).
- `bidToRetailRatioPct` = current bid ÷ retail value × 100 (`null` without a value estimate).
- `estimatedGrossMarginUSD` = retail value − current bid − repair cost, **only when both estimates exist** (otherwise `null`). A **negative margin** means Copart's repair estimate (plus the current bid) is above the value: on Copart's numbers, the lot is not worth buying.
- `isArbitrageOpportunity` is a strict, indicative flag. It is `true` only when the lot **runs and drives**, is **not parts-only**, **has bids**, **both Copart estimates exist**, the current bid is **≤ 35% of the retail value**, and `estimatedGrossMarginUSD` is **≥ $1,500**. In 500 Ford lots (2026-10-20), 6.2% were flagged (8.1% in an earlier sample of 2,000). So without `onlyArbitrageDeals` it is normal that only about 6% of the lots you get are flagged; turn it on to receive only flagged lots.
- `titleTypeRaw` is the title document exactly as Copart publishes it (for example `CERT OF TITLE-CLAIM PAID`). `titleTypeNormalized` is `CLEAN_TITLE`, `REBUILT_TITLE`, `SALVAGE_TITLE`, `NON_REPAIRABLE_PARTS_ONLY` or `OTHER`. It comes from **Copart's own title group** (clean, salvage, non-repairable); rebuilt or restored titles, which Copart groups as clean, are reported separately as `REBUILT_TITLE`. In 1,000 recent lots: clean 58.8%, salvage 33.9%, non-repairable 6.0%, rebuilt 1.3%, **`OTHER` 0%**. In the 2,000-lot sample, using the title text only: `OTHER` 0.7%.

### Pricing

**$5 per 1,000 lots** ($0.005 per lot), plus Apify's standard small fee per run start. You only pay for lots delivered to your dataset: duplicates and, in incremental mode, lots you already received are never charged.

| Example | Cost |
|---|---|
| 100 lots | ≈ $0.50 |
| 1,000 lots | ≈ $5 |
| Daily feed with ~200 new lots per day | ≈ $1 per day |

You can cap the cost of a run with Apify's maximum charge per run.

### Limitations (please read)

- **The VIN is partial.** Copart masks the last digits (`1FMEU7FEXAU******`). NHTSA specs are decoded from the visible part, which identifies make, model, year, engine and plant, but not the exact vehicle.
- **The margin is an indicative signal, not a quote.** It uses the *current* bid, which is often low days before the auction; the final price is usually higher. Copart's value and repair estimates are its own and can be wrong.
- **Incremental mode has no "newest first" order.** Copart's search does not offer it, so each run reviews the lots with the nearest auction dates (up to twice `maxItems`). A newly listed lot whose auction is far away may take a few runs to appear.
- **IAAI is experimental** and off by default: IAAI blocks datacenter IPs, so it needs a residential proxy (extra cost) and may return nothing.
- If Copart blocks or does not answer, the run **fails with a clear status message** instead of returning an empty "successful" run.

### Use it from code, n8n or Make

```bash
curl -X POST "https://api.apify.com/v2/acts/radar-scraper~copart-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"query": "toyota rav4", "maxItems": 200, "incrementalMode": true}'
```

In **n8n** or **Make**, use the Apify "Run Actor" module with the same input, then map the dataset items to your sheet, CRM or messaging tool.

### FAQ

**Does it log in to Copart?** No. It only reads what an anonymous visitor can see.
**Can I get the full VIN?** Not from public search results: Copart masks it.
**How fresh is the data?** It is read live at run time. Bids change until the auction closes.

### ⚖️ Legal & data notice

This Actor extracts publicly available information that is visible to any anonymous visitor of the source website. It does not log in, bypass paywalls, or access private areas. It does not collect personal data. You are responsible for ensuring that your use of the extracted data complies with applicable laws (including GDPR and Colombia's Law 1581 of 2012) and with the source website's terms. If you are unsure, consult a lawyer.

***

### 🇪🇸 Para importadores de Latinoamérica

**¿Importas autos de subasta de EE. UU.?** Este Actor lee las subastas de **Copart** por marca, modelo o palabra clave y te entrega, por cada lote: puja actual, fecha de subasta, daño, tipo de título, foto y las especificaciones oficiales de la **NHTSA** (motor, tracción, carrocería, planta de fabricación).

- **Feed diario de lotes nuevos:** activa `incrementalMode` y prográmalo cada día. Solo recibes (y solo pagas) los lotes que no habías recibido antes. Conéctalo con n8n o Make para enviarlos a Google Sheets, a tu CRM o a WhatsApp.
- **Filtra "Run and Drive"** (el vehículo arranca y se mueve) con margen estimado de al menos $1.500 usando `onlyArbitrageDeals`, o ordena tú por `estimatedGrossMarginUSD`.
- **Tipo de título** según la propia agrupación de Copart (limpio, salvamento, no reparable), con los títulos reconstruidos (`REBUILT_TITLE`) aparte.
- **Precio:** $5 USD por cada 1.000 lotes.
- **Ten en cuenta:** el VIN viene parcialmente oculto por Copart, el margen se calcula sobre la puja *actual* (la final suele ser mayor) y Copart no permite ordenar por "más recientes". Úsalo como una señal para priorizar, no como una cotización.

# Actor input Schema

## `query` (type: `string`):

Make, model, or vehicle keyword (e.g., 'ford f-150', 'toyota rav4', 'chevrolet silverado', 'bmw m3').

## `portals` (type: `array`):

Auctions to scrape. Copart works on standard datacenter IPs. IAAI is EXPERIMENTAL: its Imperva WAF blocks datacenter IPs, so it needs a RESIDENTIAL proxy (higher cost) and may still return nothing. Off by default.

## `enrichWithNHTSA` (type: `boolean`):

Enrich each vehicle in batch with official US DOT NHTSA technical specs (engine, displacement, body style, plant).

## `onlyArbitrageDeals` (type: `boolean`):

Only return lots that run and drive, are not parts-only, have bids, have both Copart estimates, a current bid at or below 35% of the retail value, and an estimated gross margin of at least $1,500 (about 8% of lots). The margin uses the current bid, so treat it as an indicative signal.

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

Maximum number of lots to return (and charge). About 6 minutes per 1,000 lots.

## `incrementalMode` (type: `boolean`):

When enabled, lots delivered by a previous run of the same search are skipped: not returned and not charged. The history is kept in a named key-value store in your Apify account. The search is identified by Search Query, Auctions and the arbitrage filter; changing Max Items or the proxy keeps the history. Two runs of the same search at the same time may re-deliver a few items on the next run.

## `stateKey` (type: `string`):

Optional name for the incremental history (letters, digits and ! - \_ . ' ( ) only). Leave empty to derive it from the search. Set it to keep one history across searches.

## `resetIncrementalState` (type: `boolean`):

Deletes the incremental history of this search before running, so every item is delivered as new.

## `proxyConfiguration` (type: `object`):

Apify Proxy configuration. By default uses standard Datacenter proxies to safeguard PPE margins.

## Actor input object example

```json
{
  "query": "ford",
  "portals": [
    "COPART"
  ],
  "enrichWithNHTSA": true,
  "onlyArbitrageDeals": false,
  "maxItems": 30,
  "incrementalMode": false,
  "resetIncrementalState": false
}
```

# Actor output Schema

## `lots` (type: `string`):

No description

## `runReport` (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 = {
    "query": "ford",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("radar-scraper/copart-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 = {
    "query": "ford",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("radar-scraper/copart-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 '{
  "query": "ford",
  "maxItems": 30
}' |
apify call radar-scraper/copart-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,radar-scraper/copart-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/7Hx7GGsa0KgZTSSp9/builds/Rxh9hZ8sihUubFvso/openapi.json
