# AutoTrader Canada Vehicle Listings Scraper (`automation-lab/autotrader-ca-listings-scraper`) Actor

Export public AutoTrader.ca vehicle listings with price, mileage, location, seller, images, availability, and source URLs.

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

## Pricing

from $0.43 / 1,000 item extracteds

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

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

## AutoTrader Canada Vehicle Listings Scraper

Export public AutoTrader.ca vehicle listings as structured records for Canadian inventory and price monitoring.
The Actor reads **autotrader listings** from search URLs that you configure on AutoTrader.ca and returns vehicle identity, price, mileage, seller or dealer context, location, availability, images, and canonical source URLs.

It is designed for repeatable search-result collection without loading every vehicle detail page.
That keeps scheduled monitoring fast and limits unnecessary network traffic.

### What does this AutoTrader.ca scraper do?

The Actor accepts one or more public AutoTrader.ca car search URLs.
Each URL can already contain the filters selected on AutoTrader.ca, such as:

- province or city;
- make and model;
- new or used condition;
- year and price range;
- body style, fuel type, or transmission;
- AutoTrader.ca sort order.

For every matching search result, it normalizes the available listing fields into one dataset row.
It follows result pages up to your limits, removes duplicate listing IDs, and stops as soon as `maxItems` is reached.

### Who is it for

This Actor is useful for:

- automotive market analysts comparing advertised prices and mileage;
- dealerships monitoring local inventory and competing offers;
- fleet and sourcing teams building candidate lists;
- data teams collecting recurring Canadian vehicle snapshots;
- researchers studying make, model, province, seller, or condition distributions;
- developers feeding vehicle listings into databases, dashboards, or alerts.

It collects a current snapshot.
To identify additions, removals, or price changes, schedule the Actor and compare datasets using `listingId`.

### Why use this Actor?

The output is ready for JSON, CSV, Excel, API, and automation workflows.
Compared with storing raw pages, normalized records provide:

- a stable listing identity for deduplication;
- numeric price and mileage fields for analysis;
- source search and canonical listing URLs for traceability;
- dealer and location context in the same row;
- bounded pagination and item limits;
- explicit failure when AutoTrader.ca blocks or changes the expected data shape.

The Actor does not silently treat a challenge page as an empty valid result.

### What AutoTrader listing data is extracted?

| Field | Meaning |
| --- | --- |
| `listingId` | Stable AutoTrader listing identifier |
| `legacyId` | Legacy or cross-reference identifier when exposed |
| `url` | Canonical public listing URL |
| `title` | Normalized year, make, model, and trim |
| `year`, `make`, `model`, `trim` | Vehicle identity fields |
| `vin` | VIN when present in the search result; otherwise `null` |
| `price`, `priceText`, `currency` | Numeric and displayed advertised price in CAD |
| `mileageKm`, `mileageText` | Numeric and displayed mileage |
| `transmission`, `fuelType`, `bodyType`, `engine` | Vehicle attributes exposed by the result |
| `condition` | Normalized `New` or `Used` value when known |
| `availableNow`, `availableFrom` | Availability signals exposed by AutoTrader.ca |
| `sellerType`, `sellerName`, `sellerId`, `sellerPhone` | Public seller or dealer context |
| `city`, `province`, `postalCode`, `street` | Public listing location fields |
| `distanceToSearchLocationKm` | Distance from the search location when supplied |
| `imageUrls` | Public vehicle image URLs from the result |
| `description` | Plain-text seller description when enabled |
| `vehicleDetails` | Additional labelled result-card details |
| `searchResultType` | Search placement classification when supplied |
| `sourceSearchUrl` | Exact paginated search URL that produced the row |
| `scrapedAt` | UTC extraction timestamp |

Fields that AutoTrader.ca does not provide on a result are returned as `null` or an empty array.
The Actor does not invent missing VINs or specifications.

### How to scrape AutoTrader Canada listings

1. Open AutoTrader.ca and configure the search you want to monitor.
2. Copy the resulting URL from your browser.
3. Open this Actor in Apify Console.
4. Paste the URL into **AutoTrader.ca search URLs**.
5. Set **Maximum listings** and **Maximum pages per search URL**.
6. Keep descriptions enabled if you need seller text.
7. Click **Start**.
8. Open the run dataset and export JSON, CSV, Excel, XML, or RSS.

A working Toronto input is prefilled for first-time users.

### Input parameters

#### `startUrls`

An array of public HTTPS AutoTrader.ca car search URLs.
Only `autotrader.ca` hosts and paths beginning with `/cars` are accepted.
If omitted, the Actor uses a broad nationwide car search.

#### `maxItems`

Maximum unique listings saved across all supplied URLs.
The default is 50 and the maximum is 10,000.

#### `maxPagesPerStartUrl`

Maximum result pages requested for each search URL.
The default is 10 and the maximum is 200.
This is a safety bound; the Actor may stop earlier when results are exhausted or a page repeats.

#### `includeDescriptions`

When `true`, include the public description embedded in each search result.
Set it to `false` for smaller rows when descriptions are not needed.

#### `requestDelayMs`

Delay between pages, from 0 to 30,000 milliseconds.
The default is 500 milliseconds.
A modest delay is recommended for recurring jobs.

#### `proxyConfiguration`

Optional Apify Proxy settings.
Direct HTTP is the default because the public server-rendered search currently supplies the required data.
The Actor does not automatically enable a paid residential fallback.

### Example input

```json
{
  "startUrls": [
    {
      "url": "https://www.autotrader.ca/cars/on/toronto/?rcp=20&rcs=0&srt=35"
    }
  ],
  "maxItems": 20,
  "maxPagesPerStartUrl": 1,
  "includeDescriptions": false,
  "requestDelayMs": 500
}
```

Use the AutoTrader.ca website to build precise filter URLs rather than manually guessing filter parameters.

### Example output

A current run produces rows shaped like this:

```json
{
  "listingId": "11111111-2222-3333-4444-555555555555",
  "legacyId": "70123456",
  "url": "https://www.autotrader.ca/offers/example-vehicle-11111111-2222-3333-4444-555555555555",
  "title": "2024 Example Motors Atlas Touring AWD",
  "year": 2024,
  "make": "Example Motors",
  "model": "Atlas",
  "trim": "Touring AWD",
  "vin": null,
  "price": 42995,
  "priceText": "$ 42,995",
  "currency": "CAD",
  "mileageKm": 31250,
  "mileageText": "31,250 km",
  "transmission": "Automatic",
  "fuelType": "Gasoline",
  "bodyType": "Car",
  "engine": "2,000 cc",
  "condition": "Used",
  "availableNow": true,
  "availableFrom": null,
  "sellerType": "Dealer",
  "sellerName": "Example Auto Centre",
  "sellerId": "47001234",
  "sellerPhone": "416-555-0100",
  "city": "TORONTO",
  "province": "ON",
  "postalCode": "M5V 2T6",
  "street": "100 Example Street",
  "distanceToSearchLocationKm": 12,
  "imageUrls": [
    "https://prod.pictures.autoscout24.net/listing-images/example.jpg/250x188.webp"
  ],
  "description": null,
  "vehicleDetails": {
    "Mileage": "31,250 km",
    "Transmission": "Automatic"
  },
  "searchResultType": "Organic",
  "sourceSearchUrl": "https://www.autotrader.ca/cars/on/toronto/?page=1&atype=C",
  "scrapedAt": "2026-09-16T12:00:00.000Z"
}
```

The example is anonymized but follows the real current output shape and types.

### How much does it cost to scrape AutoTrader.ca vehicle listings?

This is a pay-per-event Actor.
A run has a **$0.005 start event** plus one `item` event for each unique listing saved.
The per-listing tiers are:

| Apify tier | Price per listing |
| --- | ---: |
| FREE | $0.000828 |
| BRONZE | $0.000720 |
| SILVER | $0.0005616 |
| GOLD | $0.000432 |
| PLATINUM | $0.000432 |
| DIAMOND | $0.000432 |

At BRONZE pricing, 20 listings cost about **$0.0194**, 100 cost about **$0.077**, and 1,000 cost about **$0.725**, including one start event.
Apify may also apply plan, platform, refund, tax, correction, fraud, dispute, or clawback adjustments outside these simple event examples.
Check the live pricing panel before a production run because the applicable tier is determined by your Apify plan.

### Recurring inventory and price monitoring

A common workflow is:

1. Use a newest-first search URL for a city, province, make, or model.
2. Schedule the Actor daily or hourly in Apify Console.
3. Keep `listingId`, `price`, `mileageKm`, `availableNow`, and `scrapedAt`.
4. Join the newest dataset with the prior dataset by `listingId`.
5. Flag new IDs, missing IDs, changed prices, or changed availability.
6. Send changes to a database, spreadsheet, webhook, or alerting system.

This Actor creates snapshots; it does not retain historical state or send alerts by itself.

### Export and integration ideas

You can connect the default dataset to:

- Google Sheets for local dealer comparisons;
- BigQuery, Snowflake, or PostgreSQL for historical analysis;
- Make or Zapier for scheduled downstream actions;
- webhooks for inventory-change processing;
- Python notebooks for price and mileage distributions;
- dashboards grouped by province, make, model, or dealer.

Use `listingId` as the primary source key and keep `sourceSearchUrl` for auditability.

### Run through the Apify API

Replace `YOUR_TOKEN` with an Apify API token.
Do not commit tokens to source control.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~autotrader-ca-listings-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url": "https://www.autotrader.ca/cars/on/toronto/"}],
    "maxItems": 20,
    "maxPagesPerStartUrl": 1
  }'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/autotrader-ca-listings-scraper').call({
    startUrls: [{ url: 'https://www.autotrader.ca/cars/on/toronto/' }],
    maxItems: 20,
    maxPagesPerStartUrl: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/autotrader-ca-listings-scraper').call(run_input={
    'startUrls': [{'url': 'https://www.autotrader.ca/cars/on/toronto/'}],
    'maxItems': 20,
    'maxPagesPerStartUrl': 1,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/autotrader-ca-listings-scraper"
```

#### Claude Desktop setup

Use this MCP server entry in Claude Desktop:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/autotrader-ca-listings-scraper"
    }
  }
}
```

#### Cursor setup

Add the same `mcpServers.apify.url` value to Cursor's MCP settings.

#### VS Code setup

Add the same HTTP MCP server URL to your VS Code MCP configuration.

Example prompts:

- “Run the AutoTrader Canada scraper for this Toronto search URL and return 20 vehicles.”
- “Export Ontario listing IDs, prices, mileage, dealers, and URLs as JSON.”
- “Compare today’s dataset with yesterday’s by listing ID and summarize price changes.”

The comparison step is performed by your agent or downstream workflow, not by the Actor itself.

### Reliability, limits, and failure behavior

AutoTrader.ca can change its markup, embedded state, filters, or access controls.
The Actor currently reads structured server-rendered search data and does not fetch every detail page.
Therefore:

- VIN and some specifications can be `null` when absent from search results;
- result counts and ordering can change between pages during an active marketplace update;
- sponsored or relaxed-filter results may appear according to AutoTrader.ca behavior;
- the site may cap the number of reachable result pages;
- invalid domains and non-car paths are rejected before requests are sent;
- transient network errors, HTTP 429, and temporary server errors receive bounded retries;
- deterministic errors and changed/missing structured data fail the run visibly;
- duplicate listing IDs are saved once per run.

Use smaller scheduled searches when you need precise geographic or model coverage.

### Responsible use and legality

This Actor accesses public search-result data without logging in.
You are responsible for how you configure and use it.

- Follow AutoTrader.ca terms and applicable laws.
- Collect only data needed for a legitimate purpose.
- Avoid excessive request rates and unnecessary repeated full-market crawls.
- Do not use seller contact information for spam, harassment, or unlawful profiling.
- Respect privacy, retention, and deletion obligations that apply to your organization.
- Verify vehicle condition, price, availability, and seller claims with the source before making a decision.

This documentation is technical information, not legal advice.
AutoTrader is named only to identify the public data source; this Actor is independent and is not affiliated with or endorsed by AutoTrader.ca.

### Troubleshooting

#### Why did the run fail with a structured-data error?

AutoTrader.ca may have returned a challenge page or changed its application data.
Retry once later, verify the search URL in a normal browser, and optionally configure an appropriate Apify proxy.
Do not interpret that error as a valid empty market.

#### Why are some VIN or fuel fields null?

The Actor exports what the search result exposes.
Some fields are available only on individual detail pages, and this Actor intentionally avoids claiming detail-page-only coverage.

#### Why did the Actor save fewer records than `maxItems`?

The search may be exhausted, the site may return overlapping or repeated pages, or `maxPagesPerStartUrl` may be reached first.
Increase the page limit only when the source search contains enough distinct results.

#### Can I scrape a single vehicle detail URL?

No.
The current input contract accepts AutoTrader.ca `/cars` search URLs, not `/offers` detail URLs.
Use a focused search URL that includes the vehicle in its results.

### FAQ

#### Does it download vehicle images?

No.
It returns public image URLs and avoids downloading image files, which reduces transfer and storage cost.

#### Does it monitor changes automatically?

It produces a current snapshot.
Use an Apify schedule and compare `listingId` and price fields in a downstream system for change monitoring.

#### Are private sellers included?

They can be included when AutoTrader.ca returns them for the supplied search.
`sellerType` identifies the exposed seller category when available.

#### Does it require a proxy?

Not by default.
An optional proxy setting is available for network environments that need one, but no paid fallback is enabled automatically.

#### Is the output available as CSV or Excel?

Yes.
Open the default dataset after a run and choose JSON, CSV, Excel, XML, or another supported Apify export format.

### Related automation-lab Actors

For broader automotive or marketplace research, search the `automation-lab` Apify profile for complementary vehicle and classified-listing Actors.
This Actor is intentionally limited to public AutoTrader.ca Canadian car search results so its source fields and failure behavior remain clear.

### Support

If a run fails, include the run URL, the input search URL, expected result count, and a short description of what changed.
Do not include API tokens, private credentials, or unrelated personal data.

# Changelog

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

# Actor input Schema

## `startUrls` (type: `array`):

Public AutoTrader.ca car search URLs. Configure make, model, location, price, year, and other filters on AutoTrader.ca, then paste the resulting URL here.

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

Stop after saving this many unique vehicle listings across all search URLs.

## `maxPagesPerStartUrl` (type: `integer`):

Safety limit for pagination on each supplied search URL.

## `includeDescriptions` (type: `boolean`):

Include the public seller description embedded in each search result.

## `requestDelayMs` (type: `integer`):

Delay between search pages. Keep a small delay for respectful recurring monitoring.

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

Optional Apify Proxy configuration for runs whose network cannot reach AutoTrader.ca directly.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.autotrader.ca/cars/on/toronto/?rcp=20&rcs=0&srt=35"
    }
  ],
  "maxItems": 20,
  "maxPagesPerStartUrl": 10,
  "includeDescriptions": true,
  "requestDelayMs": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset containing every unique vehicle listing saved by the run.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.autotrader.ca/cars/on/toronto/?rcp=20&rcs=0&srt=35"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/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 = {
    "startUrls": [{ "url": "https://www.autotrader.ca/cars/on/toronto/?rcp=20&rcs=0&srt=35" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/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 '{
  "startUrls": [
    {
      "url": "https://www.autotrader.ca/cars/on/toronto/?rcp=20&rcs=0&srt=35"
    }
  ],
  "maxItems": 20
}' |
apify call automation-lab/autotrader-ca-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/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/6XLJMG40uogOdGwK5/builds/x1aaeRatNgZkW90xk/openapi.json
