# AutoTrader.ca Listings Scraper (`devilscrapes/autotrader-ca-listings-scraper`) Actor

Scrape AutoTrader.ca car listings by make, model and condition (used or new), nationwide. One clean row per listing: price, mileage, year, trim, seller, city, province, photos and description. We handle blocks, retries and proxy rotation.

- **URL**: https://apify.com/devilscrapes/autotrader-ca-listings-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## AutoTrader.ca Listings Scraper

**💰 $2.70 / 1 000 listings**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Scrape AutoTrader.ca car listings by make, model and condition (used or new), nationwide. One clean row per listing: price, mileage, year, trim, seller, city, province, photos and description. We handle blocks, retries and proxy rotation.

</div>

***

### 🎯 What this scrapes

Pulling car listings off AutoTrader.ca by hand means paging through search results, untangling the data, and keeping it all alive when pages stop answering. This Actor takes one make, one model and a condition (used or new) and returns one typed row per listing across Canada: price in CAD, mileage, year, trim, body type, seller, city, province, photos and the full description. Up to 4,000 listings per make, model and condition.

### 🔥 What we handle for you

- 🛡️ **We rotate browser fingerprints** — `curl-cffi` impersonation (Chrome / Safari) so every request looks like a real browser, not Python.
- 🌐 **We rotate residential proxies** through Apify Proxy — fresh session and exit IP on every block.
- 🔁 **We retry with exponential backoff** on `408 / 429 / 5xx` and blocked pages — up to 5 attempts per page, `Retry-After` honoured.
- 🧱 **We isolate faults** — one blocked page or one malformed listing never sinks the whole run; partial results land with a clear status message.
- 🧊 **We keep the dataset clean** — Pydantic-validated rows, de-duplicated listing IDs, numeric price and mileage, ISO-8601 timestamps.
- 💰 **You pay only for results that land.** No listings, no result charge (only the small `actor-start` fee).

### 💡 Use cases

- **Dealer pricing** — benchmark your asking prices against live listings for the same make, model and trim.
- **Valuation and price-comparison tools** — feed current Canadian asking prices and mileage into your model.
- **Market analysis** — track supply, price and mileage distribution for a model over time on a schedule.
- **Inventory sourcing** — spot underpriced used units across the country before they move.

### ⚙️ How to use it

1. Click **Try for free** at the top of the page.
2. Fill in the input form — most fields have sensible defaults.
3. Click **Start**. Output streams into the run's dataset.
4. Export from **Storage → Dataset** as JSON, CSV, or Excel — or fetch via the API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|:--:|---|---|
| `make` | `string` | no | 'toyota' | Vehicle make, for example toyota, honda or land rover. Case and spaces are normalised for you. |
| `model` | `string` | no | 'corolla' | Vehicle model, for example corolla, civic or rav4. Case and spaces are normalised for you. |
| `condition` | `string` | no | 'used' | Search used or new vehicles. |
| `maxResults` | `integer` | no | 60 | Maximum listings to emit. Each page holds 20 listings; one make, model and condition yields at most 4,000. |
| `proxyConfiguration` | `object` | no | {'useApifyProxy': True, 'apifyProxyGroups': \['RESIDENTIAL']} | Apify Proxy settings. The default uses residential exits and rotates the session on every block. |

#### Example input

```json
{
  "make": "toyota",
  "model": "corolla",
  "condition": "used",
  "maxResults": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

### 📤 Output

Every row is one dataset item.

| Field | Type | Notes |
|---|---|---|
| `listing_id` | `string` | Stable listing UUID. |
| `url` | `string` | Direct AutoTrader.ca link to the listing. |
| `title` | `string` | Year, make, model and trim. |
| `year` | `['integer', 'null']` | Model year. |
| `make` | `['string', 'null']` | Vehicle make. |
| `model` | `['string', 'null']` | Vehicle model. |
| `trim` | `['string', 'null']` | Trim / version text as the seller wrote it. |
| `body_type` | `['string', 'null']` | Body type, e.g. Sedan. |
| `price_cad` | `['integer', 'null']` | Asking price in Canadian dollars. |
| `price_formatted` | `['string', 'null']` | Price as displayed on the listing. |
| `price_evaluation` | `['integer', 'null']` | Site price rating bucket when provided. |
| `mileage_km` | `['integer', 'null']` | Odometer reading in kilometres. |
| `transmission` | `['string', 'null']` | Transmission type. |
| `fuel` | `['string', 'null']` | Fuel type. |
| `engine_cc` | `['integer', 'null']` | Engine displacement in cc when provided. |
| `condition` | `string` | used or new. |
| `city` | `['string', 'null']` | Seller city. |
| `province` | `['string', 'null']` | Province code, e.g. ON. |
| `postal_code` | `['string', 'null']` | Postal code shown on the listing. |
| `street` | `['string', 'null']` | Street address shown on the listing. |
| `seller_name` | `['string', 'null']` | Dealer or seller name. |
| `seller_type` | `['string', 'null']` | Dealer or Private. |
| `seller_phone` | `['string', 'null']` | Publicly displayed seller phone number. |
| `ad_tier` | `['string', 'null']` | Listing ad tier. |
| `result_type` | `['string', 'null']` | Organic or Sponsored. |
| `image_urls` | `array` | Listing photo URLs (may be empty). |
| `image_count` | `integer` | Number of photo URLs. |
| `description` | `['string', 'null']` | Seller description as plain text. |
| `scraped_at` | `string` | ISO-8601 UTC row-creation timestamp. |

#### Example output

```json
{
  "listing_id": "79df9408-002a-44d1-90a3-3355eb9b1770",
  "url": "https://www.autotrader.ca/offers/toyota-corolla-le-79df9408-002a-44d1-90a3-3355eb9b1770",
  "title": "2018 Toyota Corolla LE",
  "year": 2018,
  "make": "Toyota",
  "model": "Corolla",
  "trim": "LE",
  "body_type": "Sedan",
  "price_cad": 13990,
  "price_formatted": "$ 13,990",
  "price_evaluation": 1,
  "mileage_km": 144425,
  "transmission": "Automatic",
  "fuel": "Gasoline",
  "engine_cc": 1800,
  "condition": "used",
  "city": "North York",
  "province": "ON",
  "postal_code": "M3J 2E5",
  "street": "1113 Finch Ave West",
  "seller_name": "First Choice Motors",
  "seller_type": "Dealer",
  "seller_phone": "647-367-7998",
  "ad_tier": "T10",
  "result_type": "Organic",
  "image_urls": [
    "https://example.com/photo-1.webp"
  ],
  "image_count": 36,
  "description": "Certified with warranty.\nHeated seats.",
  "scraped_at": "2026-10-07T12:00:00+00:00"
}
```

### 💰 Pricing

Pay-Per-Event — you pay only when these events fire:

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.2 | One-off warm-up charge per run |
| `result` | $0.0025 | Per dataset item |

Example: 1 000 listings at the rates above ≈ **$2.70**. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

### 🚧 Limitations

- Search is by **make, model and condition (used or new)** only. There is no postal-code, radius, province, city, price, year or mileage filter, and results are nationwide.
- One make, model and condition returns at most 4,000 listings.
- Listing pages only: no VIN, full spec sheet, price history or sold/expired listings.
- Phone numbers are included only when the listing itself displays them.

### ❓ FAQ

**Can I filter by province, city or postal code?**

Not in v1. Search is by make, model and condition only, and results are nationwide. Each row carries `city`, `province` and `postal_code`, so you can filter the dataset yourself afterwards.

**How many listings can one run return?**

Up to 4,000 for a single make, model and condition (200 pages of 20). Run several models to cover more.

**What happens if nothing matches?**

The run finishes successfully with zero rows and a status message naming what was searched. An empty search is not a failure, and you are charged only the start fee.

**Do I need an AutoTrader account or API key?**

No. Everything we return is publicly displayed on the listing pages.

**Are duplicate listings removed?**

Yes. A listing that appears on more than one page is emitted once.

### 💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an
issue on the Actor's **Issues** tab on Apify Console — we ship
fixes weekly and we read every report.

***

<div align="center">

Built by **[Devil Scrapes](https://apify.com/DevilScrapes)** 😈 — a small fleet of
opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

</div>

# Changelog

This Actor's version history is a separate document: https://apify.com/devilscrapes/autotrader-ca-listings-scraper/changelog.md

# Actor input Schema

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

Vehicle make, for example toyota, honda or land rover. Case and spaces are normalised for you.

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

Vehicle model, for example corolla, civic or rav4. Case and spaces are normalised for you.

## `condition` (type: `string`):

Search used or new vehicles.

## `maxResults` (type: `integer`):

Maximum listings to emit. Each page holds 20 listings; one make, model and condition yields at most 4,000.

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

Apify Proxy settings. The default uses residential exits and rotates the session on every block.

## Actor input object example

```json
{
  "make": "toyota",
  "model": "corolla",
  "condition": "used",
  "maxResults": 60,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "make": "toyota",
    "model": "corolla",
    "condition": "used",
    "maxResults": 60,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/autotrader-ca-listings-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 = {
    "make": "toyota",
    "model": "corolla",
    "condition": "used",
    "maxResults": 60,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/autotrader-ca-listings-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 '{
  "make": "toyota",
  "model": "corolla",
  "condition": "used",
  "maxResults": 60,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call devilscrapes/autotrader-ca-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/autotrader-ca-listings-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/8Mw4RT7rUuFttVh6z/builds/i3BhGKMNmw4abZFsm/openapi.json
