# ClassicCars.com Scraper (`crawlerbros/classiccars-scraper`) Actor

Scrape ClassicCars.com listings - collector, classic, and muscle car classifieds. Filter by make/model, year, price, vehicle type, seller type, or location; fetch a listing by ID; or pull a dealer's inventory. Full specs: VIN, mileage, engine, colors, photos, seller contact.

- **URL**: https://apify.com/crawlerbros/classiccars-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Agents, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## ClassicCars.com Scraper

Scrape **ClassicCars.com** — one of the largest collector, classic, and muscle car classifieds marketplaces. Search listings by make, model, year range, price range, vehicle type, seller type, or keyword; look up individual listings by ID; or pull every listing from a specific dealer. Each listing includes full specs — VIN, mileage, engine, transmission, colors, trim, photos, and seller contact details. HTTP-only, no login, no cookies, no proxy required for normal use.

### What this actor does

- **Three modes:** `search` (browse/filter), `byIds` (exact listing lookup), `byDealer` (all listings from one dealer or auction house)
- **Full filter surface:** make, model, year range, price range, vehicle type (car/truck/SUV/motorcycle/RV/van), private-seller / dealer / auction toggles, US state or Canadian province, ZIP + radius, country, keyword search, sort order
- **Rich per-listing data:** VIN, mileage, exterior/interior color, trim, transmission, engine, title status, up to 20 photos, seller name/address/website
- **Optional lightweight mode:** turn off `fetchFullDetails` for a fast pass returning just the search-result-card fields
- **Empty fields are omitted** — every record only contains fields the site actually populated

### Output per listing

- `listingId`, `sourceUrl`, `title`
- `year`, `make`, `model`, `trim`, `bodyStyle`
- `exteriorColor`, `interiorColor`
- `transmission`, `engine`, `driveType`, `fuelType`, `numberOfDoors`, `numberOfCylinders`
- `titleStatus`, `stockNumber`, `vin`, `mileage`
- `price`, `priceCurrency`
- `description`, `descriptionSnippet`
- `location` — city, state/province
- `additionalFeatures` — any extra seller-populated spec rows the listing shows beyond the fields above (e.g. `Convertible`, `TTop`, `Seat Material`, `CD Player`, `Air Conditioning`, `Restoration History`, `Engine History`, `Exterior Condition`) — varies per listing
- `images[]` — up to 20 full-size photo URLs, `thumbnailUrl`
- `sellerType` — `private`, `dealer`, or `auctionHouse`
- `sellerName`, `sellerAddress`, `sellerPhone`, `sellerWebsite`, `dealerListingsUrl`
- `recordType: "carListing"`, `scrapedAt`

Fields like VIN, mileage, colors, trim, and seller address are only present when `fetchFullDetails` is enabled (default) — search-result cards alone don't carry them.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byIds` / `byDealer` |
| `make` | string | – | Vehicle make slug, e.g. `chevrolet`, `willys`, `ac`; free text, 300+ makes supported (mode=search) |
| `model` | string | – | Vehicle model, e.g. `camaro`; requires `make` (mode=search) |
| `keyword` | string | – | Free-text search over the listing description (mode=search) |
| `listingIds` | array | – | Numeric listing IDs (mode=byIds) |
| `dealerUrl` | string | – | Dealer or auction-house URL or `id/slug` (mode=byDealer) |
| `yearFrom` / `yearTo` | int | – | Model-year range (mode=search) |
| `priceMin` / `priceMax` | int | – | Asking-price range in USD (mode=search) |
| `vehicleType` | string | – | Car / Motorcycle / Other / RV / Truck / Van / SUV |
| `includePrivateSellers` | bool | `true` | Include private-seller listings |
| `includeDealerListings` | bool | `true` | Include dealer listings |
| `includeAuctionListings` | bool | `true` | Include auction listings |
| `country` | string | – | United States / Canada |
| `state` | string | – | US state or Canadian province (mode=search) |
| `zipCode` | string | – | US ZIP to search around |
| `distanceMiles` | string | – | Radius from `zipCode`: 25/50/100/250/500 |
| `sortBy` | string | `default` | Default / Date listed / Year / Make-Model / Price |
| `sortAscending` | bool | `false` | Sort lowest-to-highest |
| `fetchFullDetails` | bool | `true` | Visit each listing's detail page for full specs |
| `includeSellerPhone` | bool | `true` | Fetch the seller's contact phone number (mode=search/byDealer/byIds, requires `fetchFullDetails`) |
| `maxItems` | int | `20` | Hard cap on emitted records (1–1000) |

#### Example: browse Chevrolet Camaros from the 1960s, dealers only

```json
{
  "mode": "search",
  "make": "chevrolet",
  "model": "camaro",
  "yearFrom": 1965,
  "yearTo": 1970,
  "includePrivateSellers": false,
  "includeAuctionListings": false,
  "maxItems": 50
}
```

#### Example: keyword search under a price cap

```json
{
  "mode": "search",
  "keyword": "barn find",
  "priceMax": 25000,
  "maxItems": 30
}
```

#### Example: lookup specific listings by ID

```json
{
  "mode": "byIds",
  "listingIds": ["2097138", "2097122"]
}
```

#### Example: all current listings from a dealer

```json
{
  "mode": "byDealer",
  "dealerUrl": "https://classiccars.com/listings/dealer/921168/spud-s-garage",
  "maxItems": 100
}
```

#### Example: all current listings from an auction house

```json
{
  "mode": "byDealer",
  "dealerUrl": "https://classiccars.com/listings/auction/1385/carlisle-auctions",
  "maxItems": 100
}
```

### Use cases

- **Market research** — track asking prices for specific makes/models/years over time
- **Inventory monitoring** — pull a dealer's full current inventory on a schedule
- **Deal sourcing** — filter by price cap and keyword (`"project"`, `"barn find"`, `"no reserve"`) to find undervalued listings
- **Valuation tools** — feed VIN, mileage, and price into an appraisal model
- **Lead generation** — collect seller contact details for outreach
- **Regional analysis** — filter by state or ZIP radius to study a local market

### FAQ

**What's the data source?** The public listings pages at [classiccars.com](https://classiccars.com) — no login, API key, or cookies required.

**Is this affiliated with ClassicCars.com?** No, this is an independent third-party actor that reads publicly available listing pages.

**Why is `model` ignored sometimes?** `model` only applies when `make` is also set; the site's model filter is scoped per-make.

**Why do some listings lack VIN, mileage, or seller address?** Private-seller listings sometimes omit these fields, and some fields (like VIN) simply aren't always provided by the seller. The actor only emits what the listing actually shows.

**What does turning off `fetchFullDetails` change?** The actor skips the per-listing detail-page fetch and returns only the fields visible on the search-results card (title, year, make, model, price, thumbnail, location) — faster but less detailed.

**Where does `sellerPhone` come from?** ClassicCars.com reveals the seller's contact number through a "View Contact #" click on each listing page (both private-seller and dealer listings). The actor fetches this for you when `fetchFullDetails` and `includeSellerPhone` are both on. A small share of listings don't have a number on file and will simply omit the field.

**How many photos are returned per listing?** Up to 20 full-size photo URLs when `fetchFullDetails` is on.

**Why does a listing show up under `priceMax` even though it looks pricier, or has no `price` field at all?** Some listings are posted as "Call For Price" with no asking price on the site. The actor never fabricates a price for these — it omits the `price` field entirely and, since there's nothing to compare against, doesn't drop them from `priceMin`/`priceMax` filtering either.

**What if I misspell or use an invalid `make`?** ClassicCars.com's own search silently falls back to showing all makes for an unrecognized slug rather than an error. This actor guards against that: every returned record's actual make is checked against your requested `make`, so a typo or unsupported slug yields zero records (not a wall of unrelated makes).

**What if my `keyword` has no real matches?** ClassicCars.com has the same silent-fallback behavior for keyword search as it does for `make`: a keyword with zero matching listings returns the same unfiltered default feed instead of an empty result (HTTP 200, no error). This actor detects that and checks every candidate record's title/description for the keyword before emitting it, so an obscure term or unicode spelling with no real hits yields zero records rather than unrelated listings.

**What if `state` has no current listings?** Same silent-fallback behavior again: a US state or Canadian province with zero current inventory (this happens for some of the lowest-population provinces) returns the unfiltered nationwide feed instead of an empty result. The actor checks each candidate record's location text against the requested state/province and drops anything that doesn't match, so you correctly get zero records rather than unrelated listings from other regions.

**Does `zipCode` search work outside the US?** ZIP-radius search is US-only. For Canada, use `country=canada` together with `state` (a Canadian province) or a keyword/make/model filter instead.

**How fresh is the data?** Listings are scraped live on each run — as current as the site itself.

**What does `sellerType` tell me?** `private` for individual sellers, `dealer` for classic-car dealerships, and `auctionHouse` for listings posted through an auction house (e.g. Carlisle Auctions) rather than as a live online auction. `dealerListingsUrl` points to that same seller's full inventory page for both dealers and auction houses.

# Actor input Schema

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

What to fetch.

## `make` (type: `string`):

Filter to a specific vehicle make, using the site's URL slug, e.g. `chevrolet`, `ford`, `porsche`, `willys`, `ac`, `duesenberg`. ClassicCars.com lists 300+ makes, from mainstream to obscure coachbuilders, so this is free text rather than a fixed dropdown. Leave blank for all makes.

## `model` (type: `string`):

Filter to a specific model, e.g. `camaro`, `corvette`, `mustang`. Requires `make`. Leave blank for all models.

## `keyword` (type: `string`):

Free-text search across the listing description, e.g. `barn find`, `numbers matching`, `low miles`.

## `listingIds` (type: `array`):

Numeric ClassicCars.com listing IDs, e.g. `2097138` (from a listing URL `/listings/view/2097138/...`).

## `dealerUrl` (type: `string`):

Dealer or auction-house listings page URL or `id/slug`, e.g. `https://classiccars.com/listings/dealer/921168/spud-s-garage`, `921168/spud-s-garage`, or an auction house like `https://classiccars.com/listings/auction/1385/carlisle-auctions`.

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

Drop listings for model years before this year (mode=search).

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

Drop listings for model years after this year (mode=search).

## `priceMin` (type: `integer`):

Drop listings priced below this amount (mode=search).

## `priceMax` (type: `integer`):

Drop listings priced above this amount (mode=search).

## `vehicleType` (type: `string`):

Restrict to a vehicle category. Leave blank for all types.

## `includePrivateSellers` (type: `boolean`):

Include listings posted by private sellers (mode=search).

## `includeDealerListings` (type: `boolean`):

Include listings posted by dealers (mode=search).

## `includeAuctionListings` (type: `boolean`):

Include listings posted as auctions (mode=search).

## `country` (type: `string`):

Restrict to listings located in this country.

## `state` (type: `string`):

Restrict to listings located in this US state or Canadian province. Pair with `country` (united-states/canada) to disambiguate if needed; a state/province with no current listings correctly returns zero records rather than an unfiltered result.

## `zipCode` (type: `string`):

US ZIP code to search around. Used together with `distanceMiles`.

## `distanceMiles` (type: `string`):

Search radius around `zipCode`. Only applies when `zipCode` is set.

## `sortBy` (type: `string`):

Sort order for search results.

## `sortAscending` (type: `boolean`):

Sort lowest-to-highest instead of highest-to-lowest.

## `fetchFullDetails` (type: `boolean`):

Visit each listing's detail page to include VIN, mileage, engine, transmission, colors, full description, photos, and seller contact info. Slower but much richer. Turn off for a fast, lightweight pass.

## `includeSellerPhone` (type: `boolean`):

Fetch the seller's contact phone number for each listing (one extra request per listing). Only applies when `fetchFullDetails` is on. Turn off to skip and save a request per listing.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "make": "chevrolet",
  "listingIds": [
    "2097138"
  ],
  "vehicleType": "",
  "includePrivateSellers": true,
  "includeDealerListings": true,
  "includeAuctionListings": true,
  "country": "",
  "state": "",
  "distanceMiles": "",
  "sortBy": "default",
  "sortAscending": false,
  "fetchFullDetails": true,
  "includeSellerPhone": true,
  "maxItems": 20
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing all scraped ClassicCars.com listings.

# 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": "search",
    "make": "chevrolet",
    "listingIds": [
        "2097138"
    ],
    "includePrivateSellers": true,
    "includeDealerListings": true,
    "includeAuctionListings": true,
    "sortBy": "default",
    "sortAscending": false,
    "fetchFullDetails": true,
    "includeSellerPhone": true,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/classiccars-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": "search",
    "make": "chevrolet",
    "listingIds": ["2097138"],
    "includePrivateSellers": True,
    "includeDealerListings": True,
    "includeAuctionListings": True,
    "sortBy": "default",
    "sortAscending": False,
    "fetchFullDetails": True,
    "includeSellerPhone": True,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/classiccars-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": "search",
  "make": "chevrolet",
  "listingIds": [
    "2097138"
  ],
  "includePrivateSellers": true,
  "includeDealerListings": true,
  "includeAuctionListings": true,
  "sortBy": "default",
  "sortAscending": false,
  "fetchFullDetails": true,
  "includeSellerPhone": true,
  "maxItems": 20
}' |
apify call crawlerbros/classiccars-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/classiccars-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/N2O64QB7VRZuqn3JA/builds/vlpz1jbwo09FiRbMo/openapi.json
