# AutoTrader.ca Scraper: Canadian Cars and Prices (`automation_craft/autotrader-ca-scraper`) Actor

Pull AutoTrader.ca cars, trucks, RVs, boats and more from all of Canada, no login, past 4,000 ads a search. Rows hold CAD price, AutoTrader.ca price badge, model year, trim, km, VIN where shown, dealer name, phone and street. Track new ads and price drops; CSV, Excel or API; pay per listing.

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

## Pricing

from $0.42 / 1,000 listings

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.ca Scraper: Canadian Cars and Prices

**AutoTrader.ca Scraper** turns AutoTrader.ca, Canada's largest vehicle marketplace, into clean rows: one row per ad with the
price in Canadian dollars, AutoTrader.ca's own price badge (great, good or fair price), the model year, make, model and trim,
kilometres, fuel, transmission, engine, the city, province and postal code, and the seller: a dealer's name, street, phones and
dealer page, or a private seller. Search by make and model, keyword, province, postal code or city with a radius, or a dealer's
whole stock; paste search links from your browser; or give ad links, including old AutoTrader links. Cars and trucks,
motorcycles, RVs, heavy trucks, trailers, boats, watercraft, snowmobiles, heavy equipment and farm equipment. No login, no
browser.

Searches larger than AutoTrader.ca's 4,000 row limit are split on their own. Turn on **Listing details** for the full
description, the equipment list, the VIN where AutoTrader.ca shows it, the Carfax link, the dealer's stock number, colours,
drivetrain, AutoTrader.ca's market price median and the dealer's Google rating. Name a **monitor** and schedule the Actor: each
run delivers and bills only ads it has not delivered before, tracks price drops and increases, checks every ad that left the
search on its own page before it reports it removed, and can send the news to Telegram, Slack, Discord, WhatsApp or your
webhook.

#### Who uses it

- **Dealers** watching the stock and prices of other dealers in their province, and where an ad sits against AutoTrader.ca's
  price badge and market median.
- **Car buyers and brokers** tracking one model across Canada for price drops, new ads and vehicles that sold.
- **Lead and market teams** reading dealer stock with phones, street addresses, dealer pages and Google ratings.
- **Analysts and valuation tools** who need AutoTrader.ca as rows in JSON, CSV or Excel through the Apify API.

#### Features

| Feature | Settings | Event billed |
|---|---|---|
| Makes and models by name ("Toyota RAV4", "Ford F-150", "Honda Civic") or id, a trim text after " / "; 124 car makes in a pick list and the make lists of nine other vehicle types | `makeModels`, `makes` | Listing |
| AutoTrader.ca's own keyword search | `keywords` | Listing |
| Ten vehicle types: cars and trucks, motorcycles and ATVs, RVs, heavy trucks, trailers, boats, watercraft, snowmobiles, heavy equipment, farm equipment | `vehicleType` | Listing |
| Provinces and territories; postal codes, cities with their province or coordinates with a radius of 1 to 1,000 km | `provinces`, `locations`, `radiusKm` | Listing |
| A dealer's whole stock from its id or dealer page link, or within the makes you name | `dealers` | Listing |
| Pasted AutoTrader.ca search links, every part and parameter checked | `searchUrls` | Listing |
| Single ads by link or id, and old AutoTrader links (`/a/.../5_<number>`), read with their details | `adUrls` | Listing by URL |
| Named filters: condition, seller type, damaged vehicles, price, model year, kilometres, power (hp or kW), fuel, transmission, body type, drivetrain, exterior and interior colour, upholstery, paint, cylinders, price badge, equipment, certified programs, seats, doors, previous owners, online within days, price reduced | see Input | no charge |
| Any other AutoTrader.ca filter by its own parameter name | `filters` | no charge |
| Row filters: words to keep or leave out, "Price on Request" ads in or out, an online since window, ads you already have, custom rules on 36 output fields | `includeKeywords`, `excludeKeywords`, `priceOnRequest`, `postedWithinHours`, `postedWithinDays`, `postedAfter`, `postedBefore`, `excludeAdIds`, `customFilters` | no charge |
| 12 sorts, caps per run, per search and in pages, a start page | `sort`, `maxItems`, `maxItemsPerSearch`, `maxPagesPerSearch`, `startPage` | no charge |
| Past 4,000 rows a search: slices by province, seller type, model year and price, planned with count calls | `splitLargeSearches` (on) | no charge |
| Continue an interrupted run without paying for an ad twice | `resumeFromDatasetId` | no charge |
| An identical run within hours answered from the rows an earlier run stored, without reading the site again | `cacheHours` | the rows' own events |
| Full description, equipment by category, VIN, Carfax links (English and French), stock number, body type, colours, seats, doors, cylinders, drivetrain, weight, previous owners, accident flag, warranty, market price median and price bands, city and highway fuel consumption, coordinates, the date the ad went online; the dealer's homepage, logo and Google rating | `includeDetails` | Listing details |
| A monitor: only ads new to it, run after run, with or without delivering its first run | `monitorName`, `deliverBaseline` | Listing (new ads only) and Results page |
| Price drops and increases with thresholds, field changes, reappeared ads, removals checked on the ad's own page | `trackChanges`, `changeTypes`, `minPriceChange`, `minPriceChangePercent`, `trackFields` | Listing update |
| Every known ad again as a full snapshot; reposts marked or left out | `emitUnchanged`, `markReposts`, `skipReposts` | Listing (snapshot rows) |
| Notifications: Telegram, Slack, Discord, WhatsApp Cloud API, webhook (HMAC SHA-256 signature, extra headers) | see The monitor and notifications | free |
| Prices also in one of 9 other currencies at the European Central Bank's rate of the day | `currency` | included |
| Image size, description format and length, compact rows, empty fields left out, AutoTrader.ca's own record of the ad | `imageSize`, `descriptionFormat`, `descriptionMaxLength`, `compactOutput`, `excludeEmptyFields`, `includeRawRecord` | included |
| A private seller's phone numbers, seller id and exact coordinates (off by default) | `includePersonalData` | free |
| A coverage row per search, free status rows for misses, a run summary and an HTML run report (key `REPORT`) | always | free |

### Quick start

1. Type a make and model (for example `Toyota RAV4`, `Ford F-150` or `Honda Civic`).
2. Pick provinces (Ontario is preset), or give a postal code or a city with its province (`M5V 2T6`, `Calgary, AB`) and a
   radius.
3. Optional: pick filters (condition, seller type, price, model year, kilometres, fuel, transmission, price badge).
4. Set **Maximum listings** and press **Start**.
5. Download the rows as JSON, CSV or Excel, or read them through the API.

Example input, the Actor's own prefill:

```json
{
    "makeModels": ["Toyota RAV4"],
    "vehicleType": "car",
    "provinces": ["ON"],
    "maxItems": 20
}
```

Used Honda Civics from dealers within 100 km of downtown Toronto, 2019 or newer, under 80,000 km, with a great or good price
badge and the details:

```json
{
    "makeModels": ["Honda Civic"],
    "locations": ["M5V 2T6"],
    "radiusKm": 100,
    "conditions": ["used"],
    "sellerType": "dealer",
    "yearMin": 2019,
    "mileageMax": 80000,
    "priceBadges": ["great_price", "good_price"],
    "includeDetails": true,
    "maxItems": 200
}
```

Every vehicle of one dealer:

```json
{
    "dealers": ["https://www.autotrader.ca/dealers/47940832"],
    "maxItems": 1000
}
```

### What you get

One row per ad (`type: "listing"`), one coverage row per search (`type: "search"`), free status rows for anything that did
not end as a listing (`type: "status"`), with change tracking a removed row per ad that left the searches and is gone from
AutoTrader.ca (`type: "removed"`), and one run summary at the end (`type: "summary"`).

#### Listing fields

Fill rates were measured on a 1,000 row platform run on 2026-10-15 (the newest cars and trucks of all Canada, no other filter: 923 dealer and 77 private rows; `includePersonalData` off).

| Field | What it holds | Filled |
|---|---|---|
| `adId`, `url`, `legacyAdId`, `title` | AutoTrader.ca's ad id, the ad's link, the old AutoTrader number when the ad came from an old link, the title | 100 % |
| `make`, `model`, `modelGroup`, `variant`, `trim`, `engine` | as AutoTrader.ca lists them; the trim is the seller's text | make 100 %, model 100 %, trim 90.1 % |
| `vehicleType`, `condition`, `damaged` | car, motorcycle, rv and the other types; new or used; whether AutoTrader.ca marks the ad damaged | type and condition 100 %, damaged flag (true or false) 89.6 % |
| `modelYear` | the model year | 100 % |
| `price`, `currency`, `priceOnRequest`, `previousPrice`, `msrp` | the price in Canadian dollars (empty on a "Price on Request" ad, which has `priceOnRequest: true`), the price before a reduction, the maker's suggested price | price 75.3 %, on request 24.7 %, previous price 0 % (it comes on ads with a reduced price: 4,839 cars in Canada on 2026-10-15, `priceReducedOnly`), MSRP 41.1 % |
| `priceBadge`, `priceBadgeLabel`, `priceEvaluation` | AutoTrader.ca's price badge as a code (`great_price`, `good_price`, `fair_price`, `above_average_price`, `expensive`, `below_market_range`, `no_rating`), its words, the site's number | a badge other than `no_rating` 39.8 % |
| `mileageKm` | kilometres | 97.8 % |
| `fuel`, `fuelLabel`, `transmission`, `transmissionLabel`, `engineSizeCcm`, `powerKw`, `powerHp` | fuel and transmission as English codes and in the site's words; engine size; power | fuel 93.3 %, transmission 94.4 %, engine size 48.4 %, power 20.5 % |
| `province`, `city`, `postalCode`, `street`, `country`, `distanceKm` | the vehicle's place (a private seller's postal code cut to its first three characters unless `includePersonalData` is on); the street for dealers only; the distance from your place on a search with a radius | 100 %; street on 923 of 923 dealer rows |
| `sellerType`, `sellerId` | dealer or private; the dealer's id (the same on every ad of one dealer; a private seller's only with `includePersonalData`) | 100 % |
| `dealerName`, `dealerPhones`, `dealerPage` | a dealer's name, phone numbers and AutoTrader.ca dealer page | on dealer rows: name and page 100 %, phones 99.6 % |
| `privateSellerPhones` | a private seller's phones, only with `includePersonalData` | empty with it off |
| `image`, `images`, `imageCount` | the first photo, the photos the search row carries at `imageSize`, their number | 73.8 % (median 8 photos) |
| `leadsRange`, `availableNow`, `certifications`, `dealBuilderUrl`, `dealBuilderUrlFr` | AutoTrader.ca's interest band, availability, certified programs, the dealer's online deal links in English and French | leads band 100 %, certified 4.3 %, deal links 0.4 % of dealer rows |
| `placement` | `organic` (a result in the search's own order) or `promoted` (a row AutoTrader.ca inserts into the results) | 100 % |
| `missingFields` | the core fields (price, kilometres, model year, fuel, transmission, postal code, city, image) the source left empty on this ad | empty on 52.1 % of rows |
| `converted` | with `currency`: the price converted, the rate, its date and source | with a currency other than CAD |
| `searchKey`, `searchLabel`, `searchPage`, `searchSlice`, `searchPosition`, `source`, `monitorName`, `deliveryId`, `scrapedAt` | what found the ad (`search`, or `adUrl` for ad links), the search, its page, slice and position, when the row was made | set by the Actor |
| `detailsIncluded`, `pageCharged`, `cached`, `cachedAt` | whether this row's details were read and billed, whether it carried its page's Results page charge, whether it came from the cache | set by the Actor |
| `change`, `possibleRepostOf` | with a monitor: what changed since the last delivery; an earlier ad id of the same vehicle | monitor runs |

#### Listing details (`includeDetails`, and every ad link)

Measured on a 200 row platform run with details on 2026-10-15 (the newest cars and trucks of all Canada: 190 dealer and 10 private rows).

| Field | What it holds | Filled |
|---|---|---|
| `description` (and `descriptionHtml`, `descriptionMarkdown` by `descriptionFormat`) | the seller's full text | 82.0 % |
| `equipment`, `equipmentByCategory` | the equipment list, also grouped by AutoTrader.ca's categories | 82.5 % (median 18 items) |
| `images` | every photo link | 87.5 % (median 7) |
| `vin`, `carfaxUrl`, `carfaxUrlFr`, `carfaxMode` | the VIN where AutoTrader.ca shows it (inside its Carfax link), the Carfax report links | VIN 23.0 %, Carfax link 81.5 % |
| `stockNumber` | the dealer's own stock number | 98.9 % of dealer rows |
| `bodyType`, `bodyColor`, `manufacturerColor`, `interiorColor`, `paintType`, `upholstery` | as named | 100 %, 87.0 %, 62.5 %, 45.0 %, 3.5 %, 1.5 % |
| `seats`, `doors`, `gears`, `cylinders`, `driveTrain`, `weight`, `engineLitres` | as named | 72.0 %, 78.0 %, 14.0 %, 58.0 %, 84.5 %, 1.5 %, 26.0 % |
| `previousOwners`, `hadAccident`, `accidentFree`, `fullServiceHistory`, `nonSmoking`, `warranty`, `warrantyExists` | as the seller gives them | 5.0 %, 47.5 %, 47.5 %, 83.0 %, 83.0 %, 1.5 %, 100 % |
| `fuelConsumptionCity`, `fuelConsumptionHighway`, `fuelConsumptionCombined` | litres per 100 km as AutoTrader.ca shows them | city 44.0 %, highway 45.0 %, combined 0.5 % (200 rows with details, build 0.1.2, run tlHhHufwbqko1jO3f) |
| `marketPriceMedian`, `priceVsMarket`, `priceVsMarketPercent`, `priceRanges` | AutoTrader.ca's market price median for the vehicle, the ad's price against it, the price bands behind the badge | median 40.0 %, against it 40.0 %, bands 40.0 % |
| `onlineSince`, `daysOnline` | when the ad went online and days since | 100 % |
| `latitude`, `longitude` | the place (rounded to 2 decimals for private sellers with `includePersonalData` off) | 100 % |
| `dealerHomepage`, `dealerLogo`, `dealerGoogleRating`, `dealerGooglePlaceId`, `dealerGoogleMapsUrl` | the dealer's website, logo and Google rating with its Maps link | on dealer rows: homepage 56.3 %, logo 86.3 %, Google rating 67.4 % |

#### Removed rows (`trackChanges`)

`adId`, `url`, `reason`, `message`, `verified` (true: read on the ad's own page), `sourceStatus` (`removed`: AutoTrader.ca
answers that the ad is gone; `not_found`: it no longer knows the id), `lastPrice`, `firstSeenPrice`, `priceChangeCount`,
`firstSeenAt`, `daysTracked`, `monitorName`, `scrapedAt`. Written only when every search of the run was read to its end (no ad
links, no posted window, no stop). Each ad the run did not meet is read once on its own page: one that is still listed (its
price, place or details moved it out of the search) is not reported; one that could not be read waits for the next complete
run. When more than half of the tracked ads (and more than 5) are missing at once, none are reported and the run says so in a
free row.

#### Sample row (a real row of the prefill run; some fields left out)

```json
{
    "type": "listing",
    "adId": "2f4b451d-9158-491e-9459-7c1bcbc8fcc5",
    "title": "2024 Toyota RAV4 Hybrid 2.5",
    "make": "Toyota",
    "model": "RAV4",
    "variant": "RAV4 Hybrid",
    "trim": "Hybrid Limited|AWD|HEATEDCOOLEDSEATS|SUNROOF|JBL|+",
    "vehicleType": "car",
    "condition": "used",
    "modelYear": 2024,
    "price": 37587,
    "currency": "CAD",
    "priceOnRequest": false,
    "priceBadge": "great_price",
    "priceBadgeLabel": "Great price",
    "mileageKm": 143054,
    "fuel": "hybrid",
    "fuelLabel": "Gas/Electric Hybrid",
    "transmission": "automatic",
    "engineSizeCcm": 2500,
    "province": "ON",
    "city": "Toronto",
    "postalCode": "M3J 2A9",
    "street": "100 TORO ROAD",
    "sellerType": "dealer",
    "sellerId": "47940832",
    "dealerName": "FAVORIT MOTORS",
    "dealerPhones": [{ "type": "Office", "number": "833-651-4332", "callTo": "+18336514332" }],
    "dealerPage": "https://www.autotrader.ca/dealers/47940832",
    "placement": "promoted",
    "searchLabel": "Toyota RAV4 in Ontario",
    "searchPage": 1,
    "source": "search",
    "detailsIncluded": false,
    "scrapedAt": "2026-10-15T17:42:55.783Z"
}
```

#### Coverage row (one per search)

`searchKind`, `searchLabel`, `searchMakeModel`, `searchKeyword`, `searchPlace`, `searchRadiusKm`, `searchDealerId`,
`vehicleType`, `sort`, `adsOnAutoTrader` (AutoTrader.ca's total), `searchCapRows`, `slices`, `slicesWalked`, `countCalls`,
`adsBeyondReach`, `pagesRead`, `rowsSeen`, `distinctAdsSeen`, `adsDelivered`, `alreadyDelivered`, `knownToMonitor`,
`filteredOut` and `filteredOutBy` (per filter), `removedOrGone`, `detailsFailed`, `newAdsMayLieBeyond` (a monitor),
`complete`, `stoppedBy`, `morePagesOffered` and a `note`.

#### Free status rows

A setting or an item the Actor refused (`invalid`), a make or model name that matches several entries (`ambiguous`, with the
candidates), a place AutoTrader.ca does not know or places outside its province (`not_found`), an ad that was
removed (`removed`) or an id that never existed (`not_found`), an ad or a page that could not be read (`failed`), a search whose
filters AutoTrader.ca did not apply as sent (`search_not_applied`), an ad link a monitor already delivered or an ad of the
dataset you resume from (`skipped`), a cached answer (`skipped`), a notification that failed (`notification_failed`), and the
reason a run stopped (`limit_reached`, `source_unavailable`, `monitor_unavailable`). A run writes 20 such rows plus one per
billed event, at most 200 of one kind; past that it counts the rest in the summary.

#### How searches are read

- **Past 4,000 rows.** AutoTrader.ca serves at most 20 pages of 200 rows for one search, and some rows of each page are ads it
  inserts into the results (marked `placement: "promoted"`), so one walk reaches about the first 3,400 results in the search's
  order. When a search holds more and your caps want more, it is split with count calls into slices of 3,000 ads or fewer: by
  province, then seller type, then model year, then price, each slice read from its first page. Province and seller type
  divide every ad exactly; model year slices miss ads without a year and price slices miss "Price on Request" ads, so the
  coverage row counts anything no slice held as `adsBeyondReach`.
- **Every filter checked.** AutoTrader.ca answers an unknown parameter with a wider search and repeats it in its echo. The
  Actor sends only parameters from AutoTrader.ca's own filter map, refuses a pasted link with any other, compares the echo
  with what it sent on every page, and checks every row against the filters it can read (price, kilometres, model year,
  power, fuel, transmission, seller type, condition, damaged state, province, price badge, dealer, make and model, vehicle
  type); a page
  that differs is billed as nothing and gets a free `search_not_applied` row.
- **Places.** A postal code or a city is placed by AutoTrader.ca itself, once per run, with a count call, and must come back
  with coordinates inside its own province (a postal code's first letter names its province); a place the site cannot place,
  or places elsewhere, is a free row and its searches are not read. A city needs its province code (`Halifax, NS`).
- **Empty answers.** AutoTrader.ca now and then answers a full search with an empty page (about 1 or 2 calls in 100); such a
  page is asked again before the walk ends.
- **One row per ad.** An ad found by several searches in one run is delivered and billed once.
- **Access.** Requests leave from the run's own address, two at a time and at most 3 a second by default; Apify's datacenter
  proxy is used only when that address cannot reach the site. A refusal is asked once more on the same exit after a pause; a
  second refusal ends the run's reading with a free `source_unavailable` row.

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

You pay per listing row delivered, plus a small start fee per run. Platform usage is included.

| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| Listing (per 1,000 ads from searches, search links and dealer stock) | $0.49 | $0.49 | $0.49 | $0.42 |
| Results page (per 1,000 pages of up to 200 ads that delivered a paid row; in a monitor run, every page read) | $0.50 | $0.45 | $0.40 | $0.35 |
| Listing details (per 1,000 rows, only with `includeDetails`) | $1.00 | $0.90 | $0.80 | $0.70 |
| Listing by URL (per 1,000 ads from `adUrls`, details included) | $1.49 | $1.39 | $1.29 | $1.12 |
| Listing update (per 1,000 changes and removed rows, monitor runs with `trackChanges` only) | $0.49 | $0.49 | $0.49 | $0.42 |
| Actor start (per run) | $0.0045 | $0.0045 | $0.0045 | $0.0045 |

Platinum and Diamond plans pay the Gold price. On Apify's Free plan the Actor runs like on any other plan, at the Free
prices, with no row limit of its own. The Actor start event is a flat $0.0045, charged once per run, with no plan
discount. The Store pricing card shows these same prices per 1,000 events: "$0.49 / 1,000" on the Listing row means one
listing costs $0.00049, and "$1.39 / 1,000" on the Listing by URL row means one ad from a link costs $0.00139.

- **4,500 listings from one search** (a measured run past the 4,000 row limit: 4,500 Listings, 25 Results pages, 1 Actor
  start) cost $2.205 + $0.0125 + $0.0045 = **$2.222** on Free, $2.205 + $0.01125 + $0.0045 = **$2.22075** on Bronze,
  $2.205 + $0.01 + $0.0045 = **$2.2195** on Silver and $1.89 + $0.00875 + $0.0045 = **$1.90325** on Gold.
- **200 listings with details** on Bronze (a measured run: 200 Listings, 200 Listing details, 1 Results page) cost
  200 x $0.00049 + 200 x $0.0009 + $0.00045 + $0.0045 = $0.28295.
- **100 ad links** on Bronze cost 100 x $0.00139 = $0.139, plus $0.0045: $0.1435.
- **A monitor run** on Bronze over 2 searches reads 3 pages each (6 x $0.00045 = $0.0027); with 12 new listings it costs
  $0.0027 + 12 x $0.00049 + $0.0045 = $0.01308.
- **What is never billed:** ads left out by your filters, an ad found twice in one run, ads a monitor already delivered
  (unless change tracking finds a change, or you ask for a full snapshot), removed and unknown ads, a page whose filters
  AutoTrader.ca did not apply, count calls, place and old link lookups, the reads that check a removal, coverage, status and
  summary rows, the run report and the notifications.
- **Limits:** set **Maximum listings** (100 when left empty) and, in the run options, a maximum charge for the run: the
  Actor stops before it would pass either, and a row whose events do not all fit is withheld whole. Maximum listings counts
  listings, changes and removed rows together. A run also spends a small allowance on work that delivers nothing billable
  (count calls, place and old link lookups, pages whose ads your filters leave out, removal checks), USD 0.0006 plus a share
  of every paid event it delivers; past it the run stops with a free row that says so.

### Input

| Setting | What it does |
|---|---|
| `makeModels` | makes, or makes with a model, as AutoTrader.ca lists them; a trim text after " / "; ids such as `70` or `70|2143`; the names follow the vehicle type |
| `makes` | car makes picked from AutoTrader.ca's list of 124 |
| `keywords` | free text for AutoTrader.ca's own keyword search, each its own search |
| `vehicleType` | car (default), motorcycle, rv, heavy_truck, trailer, boat, watercraft, snowmobile, heavy_equipment, farm_equipment |
| `provinces` | province and territory codes (`ON`, `QC`, `BC`, `AB`, `MB`, `SK`, `NS`, `NB`, `NL`, `PE`, `YT`, `NT`, `NU`) or names; each its own search |
| `locations`, `radiusKm` | postal codes (`M5V 2T6`), cities with their province (`Toronto, ON`) or coordinates (`43.65, -79.38`); a radius of 1 to 1,000 whole km (50 by default) |
| `dealers` | dealer ids (`sellerId` of a row) or dealer page links (`https://www.autotrader.ca/dealers/<id>`): alone, the whole stock; with makes, the dealer's stock within those makes |
| `searchUrls` | AutoTrader.ca search links (`https://www.autotrader.ca/cars/...`); a part or parameter the Actor does not know refuses the link with a free row |
| `adUrls` | ad links, ad ids or old AutoTrader ad links, each billed as a Listing by URL |
| `resumeFromDatasetId` | the dataset of an earlier run of this Actor: its ads are left out, free (up to 500,000 rows read) |
| named filters | `conditions`, `sellerType`, `damagedVehicles`, `minPrice` to `maxPrice`, `yearMin` to `yearMax`, `mileageMin` to `mileageMax`, `powerMin` to `powerMax` with `powerUnit`, `fuelTypes`, `transmission`, `bodyTypes`, `driveTypes`, `colors`, `interiorColors`, `upholstery`, `paintTypes`, `cylinders`, `priceBadges`, `equipment`, `certifications`, `seatsMin` to `seatsMax`, `doorsMin` to `doorsMax`, `previousOwnersMax`, `onlineWithinDays`, `priceReducedOnly` |
| `filters` | any other AutoTrader.ca parameter by its own name and value; an unknown name refuses the run with a free row |
| row filters | `includeKeywords`, `excludeKeywords`, `priceOnRequest`, `customFilters`, `postedWithinHours`, `postedWithinDays`, `postedAfter`, `postedBefore` (need details and the newest or oldest sort), `excludeAdIds` (up to 5,000) |
| `sort` | newest (default), oldest, price_low, price_high, mileage_low, mileage_high, year_new, year_old, power_high, power_low, best, distance (needs a place) |
| `maxItems`, `maxItemsPerSearch`, `maxPagesPerSearch`, `startPage`, `splitLargeSearches` | caps (100 listings when `maxItems` is left empty) and how far each search is read |
| `includeDetails`, `includeRawRecord` | the details add-on; AutoTrader.ca's own record of each ad |
| `cacheHours` | answer an identical run within 1 to 720 hours from the rows an earlier full run stored (up to 2,000 rows; not with a monitor) |
| `currency`, `imageSize`, `descriptionFormat`, `descriptionMaxLength`, `compactOutput`, `excludeEmptyFields` | how rows are written |
| `includePersonalData` | a private seller's phones, seller id, full ad link and exact coordinates (off by default; see Privacy) |
| monitor and notifications | `monitorName`, `deliverBaseline`, `trackChanges`, `changeTypes`, `minPriceChange`, `minPriceChangePercent`, `trackFields`, `emitUnchanged`, `markReposts`, `skipReposts`, `notificationLimit`, `notifyOnlyChanges` and the channel settings below |
| `failIfIncomplete`, `maxFailedRequestsPercent`, `requestsPerSecond`, `maxRequestRetries`, `maxConcurrency`, `proxyConfiguration` | fail the run when a search was not read to its end or too many reads failed; the pace (0.5 to 4 a second, 3 by default), retries, requests at once (1 to 4, 2 by default); the run's own address (default), Apify datacenter, or your own proxy links |

A run holds up to 200 searches (makes and models x keywords x places x dealers, plus one per search link) and up to 5,000
ad links.

### The monitor and notifications

Name a monitor (`monitorName`) and schedule the Actor (every hour, for example). The monitor remembers every ad it delivered
in a named store this Actor creates for itself, up to 35,000 ads, so each run delivers and bills only ads it never delivered
before; known ads are skipped for free. A monitor reads newest first, the newest 3 pages of 200 ads of each search by
default (set `maxPagesPerSearch` to change it), does not split searches, and pays a Results page for each page it reads;
when the coverage row says `newAdsMayLieBeyond`, raise the pages or run more often. With `deliverBaseline` off, the first run
only stores the ads its searches list now (after your filters), and later runs deliver what is new; such a monitor takes no
ad links and no details add-on (its first run reads no details). One monitor name belongs to one set of
settings: a run with other settings delivers nothing and gets a free row saying so.

- **Change tracking** (`trackChanges`): a known ad whose price changed comes back with `change` (direction, previous price,
  difference, first seen price, dated price history, drop in percent since first seen), billed as a Listing update.
  `minPriceChange` (dollars) and `minPriceChangePercent` leave smaller moves out, measured from the price last delivered (they
  add up until one passes);
  `changeTypes` picks price drops, price increases, field updates, reappeared and removed ads. With `trackFields` a change of
  other fields counts too (`changeType: "updated"`, `changedFields`). Removed ads: see Removed rows above.
  Changes are found on the search rows a monitor reads: a value only the details show (a trim missing from the search row) is
  compared when the ad's details are read for another reason (a price or another field changed).
- **Snapshots and reposts:** `emitUnchanged` delivers known ads again (billed as Listing); `markReposts` marks a new ad with
  the same seller, make, model, model year, kilometres and trim as one the monitor delivered earlier under another id
  (`possibleRepostOf`), and `skipReposts` leaves it out free.
- **Notifications** (free, with or without a monitor) after the rows were delivered and billed: Telegram (your own bot, one
  message per listing), Slack and Discord incoming webhooks and WhatsApp Cloud API (one message per run), each naming up to
  `notificationLimit` listings (10 by default, up to 30); a webhook (`webhookUrl`) gets JSON batches of 100, up to 1,000 a
  run, signed in the header `x-signature-sha256` with `webhookSecret` (8 to 200 characters), with your own
  `webhookHeaders`. A failed call never fails the run: it is a free `notification_failed` row, without your address or
  token.

### Privacy and personal data

Private sellers are private persons. With `includePersonalData` off (the default), the phone numbers AutoTrader.ca shows for
them, their seller id and AutoTrader.ca's own record of their ad are not delivered, their exact coordinates are rounded to 2
decimals (about 1 km), their postal code is cut to its first three characters (the forward sortation area, `M4E` for
`M4E 3T5`), and their `url` is the id only link (the ad's own link repeats the seller's trim text). With it on, those come as
AutoTrader.ca shows them. Texts are never changed: the title, trim and description (text, Markdown and HTML) come exactly as
AutoTrader.ca serves them, switch on or off, including any phone number or e-mail address a seller wrote into them.
AutoTrader.ca shows no private seller's name or street. A dealer's name, address,
phones, homepage and rating are business data and are always delivered. Photos are delivered as links; they belong to
the people who posted them. You are responsible for a lawful use of personal data, PIPEDA and Quebec's Law 25 included.

### Legal

This Actor is not affiliated with, endorsed by or sponsored by AutoTrader.ca or Trader Corporation. AutoTrader.ca is a
trademark of its owner. It is an unofficial tool that reads public pages without logging in. AutoTrader.ca's terms of use
forbid access by automated means and the collection of its content. You are responsible for a lawful use of the data, for complying with Canadian privacy
law for any personal data, and for keeping a scheduled monitor to what you need.

### What this Actor does NOT do

- **No login, no messages to sellers, no offers, no saved searches or anything else that needs an AutoTrader.ca account.**
- **No private seller phone numbers, seller ids or exact coordinates unless you turn on `includePersonalData`.** Dealers'
  business contacts are always delivered.
- **No VIN recovered from other sites.** The VIN comes only where AutoTrader.ca shows it (inside its Carfax link: 23 and
  65 percent of the ads in two runs of 2026-10-15); no other marketplace is searched for a hidden VIN.
- **No merging with other marketplaces** (Kijiji, CarGurus, Carpages). This Actor reads AutoTrader.ca only.
- **No dealer e-mail addresses.** AutoTrader.ca shows none, and the dealer's own website is not read; rows carry the
  dealer's phones, street, homepage link and dealer page.
- **No electric range or dealer opening hours.** AutoTrader.ca served none on 205 ads read with details in our tests of
  2026-10-15 (3 of them electric).
- **No Carfax reports.** The Carfax links are delivered as AutoTrader.ca shows them; the reports are not opened.
- **No more than 4,000 rows from one AutoTrader.ca page walk.** Past that the search is split automatically
  (`splitLargeSearches`, on by default, not in a monitor); what a split cannot reach is counted on the coverage row.
- **No export into Notion or other apps from inside the run.** Connect the dataset with Apify's integrations, using your own
  accounts.
- **No ready made example tasks yet.** Start from the prefill or the examples above.
- **No preloaded snapshot.** Every run reads AutoTrader.ca live (or, with `cacheHours`, reuses your own earlier run's rows);
  the data is as fresh as the run.

### FAQ

#### Does AutoTrader.ca have an API?

AutoTrader.ca publishes no public API for reading its ads. This Actor reads the same public ads any visitor sees, with no login, and gives them to you as rows you can read through the Apify API
(examples below).

#### Is it legal to scrape AutoTrader.ca?

This Actor reads only public ads without logging in, and a private seller's phone number comes only when you turn it on.
AutoTrader.ca's terms forbid automated access, so you are responsible for a lawful use of the data, Canadian privacy law
included (see Legal).

#### How many cars can one AutoTrader.ca search return?

AutoTrader.ca serves at most 4,000 rows (20 pages of 200) for one search, and some of them are ads it inserts into the
results, so one walk reaches about the first 3,400 results. Past that, this Actor splits the search by province, seller type,
model year and price on its own and reads every slice; the coverage row gives AutoTrader.ca's total, the slices read and
anything left beyond reach.

#### What does the AutoTrader.ca price badge mean?

It is AutoTrader.ca's own rating of an ad's price against the market: great price, good price, fair price, above average
price, or none. Every row carries it as a code (`priceBadge`) and in the site's words (`priceBadgeLabel`), you can search by it
(`priceBadges`), and with details each row also carries AutoTrader.ca's market price median and the ad's price against it.

#### How do I get alerts for new AutoTrader.ca listings or price drops?

Name a monitor and schedule the Actor, every hour for example. Each run delivers and bills only ads the monitor has not
delivered before; with change tracking it also delivers price drops and removed ads, and it can send them to Telegram, Slack,
Discord, WhatsApp or your webhook.

#### Why does this Actor run with limited permissions?

It needs nothing beyond its own storages: it reads AutoTrader.ca's public ads and writes to its own dataset and key-value
store. Limited permissions keep it from touching anything else in your account. A monitor's memory and the result cache are
named stores the Actor creates for itself.

### Use it from AI agents (MCP)

AI agents can run this Actor as a tool through Apify's MCP server (`https://mcp.apify.com`, add `automation_craft/autotrader-ca-scraper`
to its tools) or through the API below. For agents, set `compactOutput` (only the core fields on each row) and
`excludeEmptyFields`, keep `maxItems` small, and read the coverage row (`type: "search"`) to see whether a search was read to
its end.

### API

Each example starts a run and waits for its rows (the run-sync endpoint suits short runs; use `maxItems` to keep them short).

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~autotrader-ca-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"makeModels": ["Toyota RAV4"], "provinces": ["ON"], "maxItems": 20}'
```

```js
const res = await fetch('https://api.apify.com/v2/acts/automation_craft~autotrader-ca-scraper/run-sync-get-dataset-items', {
    method: 'POST',
    headers: { Authorization: 'Bearer <YOUR_API_TOKEN>', 'Content-Type': 'application/json' },
    body: JSON.stringify({ makeModels: ['Toyota RAV4'], provinces: ['ON'], maxItems: 20 }),
});
const rows = await res.json();
console.log(rows.filter((r) => r.type === 'listing'));
```

```python
import requests

res = requests.post(
    "https://api.apify.com/v2/acts/automation_craft~autotrader-ca-scraper/run-sync-get-dataset-items",
    headers={"Authorization": "Bearer <YOUR_API_TOKEN>"},
    json={"makeModels": ["Toyota RAV4"], "provinces": ["ON"], "maxItems": 20},
    timeout=330,
)
listings = [r for r in res.json() if r["type"] == "listing"]
```

### Changelog

See the Changelog tab. 0.1: first release.

### More data tools by Automation Craft

- [Kijiji Scraper: Listings, Cars, Rentals & Prices](https://apify.com/automation_craft/kijiji-scraper)
- [Mobile.de Scraper: Cars, Prices, Dealers & Ratings](https://apify.com/automation_craft/mobile-de-scraper)
- [Facebook Marketplace Scraper with Sold Tracker](https://apify.com/automation_craft/facebook-marketplace-scraper)
- [OfferUp Scraper: Local Listings, Prices, Sellers](https://apify.com/automation_craft/offerup-scraper)
- [Leboncoin Scraper: Ads, Prices, Real Estate & Cars](https://apify.com/automation_craft/leboncoin-scraper)
- [Kleinanzeigen Scraper & API: Ads, Prices, Places](https://apify.com/automation_craft/kleinanzeigen-scraper)

# Changelog

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

# Actor input Schema

## `makeModels` (type: `array`):

Makes, or makes with a model, as AutoTrader.ca lists them: "Toyota", "Toyota RAV4", "Ford F-150", "Honda Civic", and a trim text after " / " ("Toyota RAV4 / XLE"). Ids work too ("70", "70|2143"). A name that matches several models is a free row with the candidates. The names follow the vehicle type below.

## `makes` (type: `array`):

Car makes picked from AutoTrader.ca's own list (124 makes); each is searched like a make written in "Makes and models". Cars and trucks only.

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

The kind of vehicle every built search reads. Default: cars and trucks. Choosing a type with no make, place or other filter reads all of Canada for that type, newest first.

## `keywords` (type: `array`):

Free text AutoTrader.ca searches in the ads (its own keyword search), such as "sunroof", "AWD", "one owner". Each keyword is its own search.

## `provinces` (type: `array`):

Search these provinces or territories (each is its own search). Leave empty for all of Canada.

## `locations` (type: `array`):

A Canadian postal code ("M5V 2T6"), a city with its province code ("Toronto, ON", "Halifax, NS") or coordinates ("43.65, -79.38"), searched with the radius below. AutoTrader.ca places each postal code or city itself, once per run; one it cannot place, or places outside the province named (a postal code names its province by its first letter), is a free row and its searches are not read.

## `radiusKm` (type: `integer`):

The radius around each place in whole kilometres, 1 to 1,000 (the site's form offers 10 to 400). Default 50 km when a place is given.

## `dealers` (type: `array`):

A dealer's stock: its id (the "sellerId" of its rows) or its dealer page link (https://www.autotrader.ca/dealers/47946545). With no make it reads the whole stock; with makes, keywords or filters, the stock within them.

## `searchUrls` (type: `array`):

AutoTrader.ca search links copied from your browser after choosing a make and filters (https://www.autotrader.ca/cars/toyota/rav4/reg_on?...). Each is read with its own path parts and filters (the site applies them; the run checks on every page that it did); a parameter or path part this Actor does not know refuses the link (the site would ignore it and search wider).

## `adUrls` (type: `array`):

AutoTrader.ca ad links (https://www.autotrader.ca/offers/...), ad ids, or old AutoTrader ad links (/a/.../5\_<number>...), read with their details and delivered as given (billed as Listing by URL). A removed or unknown ad is a free row.

## `resumeFromDatasetId` (type: `string`):

The dataset id of an earlier run of this Actor in your account (its "defaultDatasetId"). Ads delivered in it are left out, free, so an interrupted run can be continued without paying for an ad twice. At most 500,000 rows are read.

## `conditions` (type: `array`):

New or used vehicles (both by default).

## `sellerType` (type: `string`):

Dealers, private sellers, or both (default).

## `damagedVehicles` (type: `string`):

AutoTrader.ca leaves damaged vehicles out of its searches unless asked; about 1,100 are listed across Canada. Each row says whether the ad is marked damaged (`damaged`).

## `minPrice` (type: `integer`):

Lowest price in Canadian dollars. "Price on Request" ads are left out of any price filter by the site.

## `maxPrice` (type: `integer`):

Highest price in Canadian dollars.

## `yearMin` (type: `integer`):

Earliest model year.

## `yearMax` (type: `integer`):

Latest model year.

## `mileageMin` (type: `integer`):

Lowest odometer reading in km.

## `mileageMax` (type: `integer`):

Highest odometer reading in km.

## `powerMin` (type: `integer`):

Lowest power, in the unit below (hp by default).

## `powerMax` (type: `integer`):

Highest power, in the unit below (hp by default).

## `powerUnit` (type: `string`):

The unit of "Power from" and "Power up to". Default hp.

## `fuelTypes` (type: `array`):

Any of these fuels.

## `transmission` (type: `array`):

Automatic or manual.

## `bodyTypes` (type: `array`):

Any of these body types, by the site's name or number: "Hatchback" (1), "Convertible" (2), "Coupe" (3), "Wagon" (5), "Sedan" (6), "Minivan" (12), "SUV" (14), "Pick-up Truck" (15), "Others" (7) for cars; other vehicle types have their own lists (a name the type does not list is refused).

## `driveTypes` (type: `array`):

Any of these drivetrains.

## `colors` (type: `array`):

Any of these exterior colours, by name: "Beige", "Blue", "Brown", "Bronze", "Yellow", "Grey", "Green", "Red", "Black", "Silver", "Violet", "White", "Orange", "Gold".

## `interiorColors` (type: `array`):

Any of these interior colours, by name: "Beige", "Black", "Grey", "Brown", "Other", "Blue", "Red", "Green", "Yellow", "Orange", "White".

## `upholstery` (type: `array`):

Any of these upholsteries: "Alcantara", "Cloth", "Full leather", "Other", "Part leather", "Velour".

## `paintTypes` (type: `array`):

Any of these paint types: "Metallic", "Others", "Perl Effect", "Mica (Stoned)", "Uni/Basic".

## `cylinders` (type: `array`):

Any of these cylinder counts (ads that state none are left out by the site).

## `priceBadges` (type: `array`):

Any of these AutoTrader.ca price badges (its own rating of the price against the market).

## `equipment` (type: `array`):

Equipment every vehicle must have, by its name as the site lists it or its number: "Blind spot monitor", "Heated seats", "Navigation system", "Sunroof", "Apple CarPlay" and the others of the site's list (136 items), plus "With full service history" and "Non-smoking vehicle".

## `certifications` (type: `array`):

Vehicles of any of these certified programs, by name or number as the site lists them: "GM Certified", "Honda Certified", "Toyota Certified", "Nissan Certified", "BMW Certified", "Acura Certified", "Lexus Certified", "Volkswagen Certified" and the others.

## `seatsMin` (type: `integer`):

Fewest seats.

## `seatsMax` (type: `integer`):

Most seats.

## `doorsMin` (type: `integer`):

Fewest doors.

## `doorsMax` (type: `integer`):

Most doors.

## `previousOwnersMax` (type: `integer`):

At most 1, 2 or 3 previous owners (4 means 4 or more, as on the site).

## `onlineWithinDays` (type: `integer`):

Ads online for at most this many days, as AutoTrader.ca filters them: 1 to 7, or 14.

## `priceReducedOnly` (type: `boolean`):

Only ads whose price was reduced (the site's "Reduced" filter).

## `filters` (type: `object`):

Any other filter of the site, by its own parameter name and value, such as {"seatsfrom": 7, "bcol": \["11"]}. A name this Actor does not know refuses the run (the site would ignore it and search wider).

## `includeKeywords` (type: `array`):

Whole words looked for in the title, trim and description (and the equipment when details are read). A row needs one of them.

## `excludeKeywords` (type: `array`):

Whole words that leave a row out, looked for where the words above are.

## `priceOnRequest` (type: `string`):

Ads that show no price ("Price on Request"; one in five of the newest ads). Included by default, with an empty price and priceOnRequest true.

## `customFilters` (type: `array`):

Rules on 36 output fields (price, mileageKm, modelYear, powerHp, city, dealerName, vin and others), all of which must hold: \[{"field": "powerHp", "op": "gte", "value": 200}, {"field": "city", "op": "notEquals", "value": "Toronto"}]. Ops: includes, notIncludes, equals, notEquals, gt, gte, lt, lte.

## `excludeAdIds` (type: `array`):

Ad ids or links never delivered.

## `postedWithinHours` (type: `integer`):

Only ads that went online within this many hours of the run's start (needs details on; the moment is on the details).

## `postedWithinDays` (type: `integer`):

Only ads that went online within this many days of the run's start (needs details on).

## `postedAfter` (type: `string`):

Only ads that went online on or after this day, YYYY-MM-DD in UTC (needs details on).

## `postedBefore` (type: `string`):

Only ads that went online on or before this day, YYYY-MM-DD in UTC (needs details on).

## `sort` (type: `string`):

The order of every built search. Default: newest first. A search link keeps its own sort.

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

The most listing rows the run delivers (searches, links and updates together). Default 100.

## `maxItemsPerSearch` (type: `integer`):

The most listing rows one search delivers.

## `maxPagesPerSearch` (type: `integer`):

The most result pages (200 rows each) one search reads. A monitor reads 3 by default.

## `startPage` (type: `integer`):

The result page each search starts on (not with a monitor).

## `splitLargeSearches` (type: `boolean`):

On by default: a search with more ads than one walk reaches (about 3,400 of the site's 4,000 row cap) is split into slices with count calls (province, seller type, model year, price), so every ad is read; the coverage row counts any ad no slice could hold. Off for monitors.

## `includeDetails` (type: `boolean`):

Read each search row's details: the full description, the equipment list, body type, colours, drivetrain, seats, doors, cylinders, city and highway fuel consumption where shown, the VIN where AutoTrader.ca shows it (inside its Carfax link: 23 and 65 percent of the ads in two of our runs), the Carfax report link, the dealer's stock number, Google rating and homepage, the market price median with the price against it, coordinates, and the moment the ad went online. Billed as Listing details per row read.

## `includeRawRecord` (type: `boolean`):

Attach AutoTrader.ca's own record of the ad (and of its details when read) to each row, as "rawRecord". Private sellers' records only with personal data on. Free.

## `includePersonalData` (type: `boolean`):

Off by default. On: private sellers' phone numbers as AutoTrader.ca shows them, their seller id, the ad's full link, their exact coordinates, their full postal code and their source record when asked for (off, those are left out, coordinates rounded to about 1 km and the postal code cut to its first three characters). Titles, trims and descriptions are always delivered exactly as AutoTrader.ca serves them, whatever this setting. Dealers' contact details are business data and always delivered. You are responsible for a lawful use, PIPEDA and privacy laws included.

## `currency` (type: `string`):

Prices stay in Canadian dollars; another currency adds a converted price at the European Central Bank's rate of the day.

## `imageSize` (type: `string`):

The size of the image links. Default large.

## `descriptionFormat` (type: `string`):

The format of the description.

## `descriptionMaxLength` (type: `integer`):

Cut descriptions to this many characters.

## `compactOutput` (type: `boolean`):

Only the core fields on each row (what a row paid for stays).

## `excludeEmptyFields` (type: `boolean`):

Drop fields that are empty on a row.

## `monitorName` (type: `string`):

A short name ("rav4-ontario"). The monitor remembers every ad it delivered; known ads are free. One name holds one set of settings.

## `deliverBaseline` (type: `boolean`):

On by default: the monitor's first run delivers the ads its searches list now. Off: the first run stores them as known without delivering them (only the results pages read are charged), and later runs deliver what is new or changed. Off cannot be combined with ad links or with the details add-on (the first run reads no details).

## `trackChanges` (type: `boolean`):

Also deliver known ads whose price (or a tracked field) changed or that came back, and ads that left every search (removed), billed as Listing update.

## `changeTypes` (type: `array`):

Which changes a monitor with change tracking delivers. Default: all.

## `minPriceChange` (type: `number`):

A price change smaller than this many dollars is not delivered; the price last delivered stays the baseline, so small changes add up.

## `minPriceChangePercent` (type: `number`):

A price change smaller than this share of the price last delivered is not delivered.

## `trackFields` (type: `array`):

The fields whose change makes a Listing update. Default: price. Compared on the search rows the monitor reads (a value only the details show is compared when they are read).

## `emitUnchanged` (type: `boolean`):

Deliver known ads without a change as well (billed as Listing), each marked unchanged.

## `markReposts` (type: `boolean`):

Mark a new ad whose vehicle the monitor delivered under another id (same seller, make, model, model year, kilometres and trim).

## `skipReposts` (type: `boolean`):

Leave such reposts out (free).

## `webhookUrl` (type: `string`):

Rows are POSTed here in batches of 100 (JSON).

## `webhookSecret` (type: `string`):

Signs each batch (HMAC SHA-256, header X-Signature-Sha256).

## `webhookHeaders` (type: `object`):

Extra headers, such as {"Authorization": "Bearer ..."}.

## `telegramBotToken` (type: `string`):

The token BotFather gave your bot.

## `telegramChatId` (type: `string`):

Your chat id, or a channel name starting with @.

## `slackWebhookUrl` (type: `string`):

An incoming webhook of your Slack workspace.

## `discordWebhookUrl` (type: `string`):

A webhook of your Discord channel.

## `whatsappAccessToken` (type: `string`):

Your WhatsApp Cloud API token.

## `whatsappPhoneNumberId` (type: `string`):

The id of your WhatsApp Cloud API number.

## `whatsappTo` (type: `string`):

The number to message, international form without +.

## `notificationLimit` (type: `integer`):

The most listings named in each chat message. Default 10.

## `notifyOnlyChanges` (type: `boolean`):

With a monitor, leave unchanged ads out of the messages (default on).

## `failIfIncomplete` (type: `boolean`):

Mark the run failed when a search or ad link was not read completely (the rows stay delivered).

## `maxFailedRequestsPercent` (type: `integer`):

Mark the run failed when more than this share of its pages and ad reads failed (the rows stay delivered).

## `requestsPerSecond` (type: `number`):

The pace of requests to AutoTrader.ca (default 3).

## `maxRequestRetries` (type: `integer`):

How many times a page or ad read that failed is asked again (default 2; 0 sends each read once). A refusal by the site is asked again once, on the same address after a pause, when retries are left; a second refusal ends the reading of the run.

## `maxConcurrency` (type: `integer`):

How many requests to AutoTrader.ca run at once (default 2); the pace above still holds.

## `cacheHours` (type: `integer`):

When set, a run whose settings are all the same as an earlier run within this many hours is answered from the rows that run stored (up to 2,000 rows; billed as fresh rows of their kind, no results page; each row carries "cached": true and the moment it was read), without reading AutoTrader.ca. A run that reads everything it was asked stores its rows. Not with a monitor.

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

Leave it as it is: the run reads from its own address and uses Apify's datacenter proxy only when that address cannot reach the site. "Use Apify proxy" starts with the datacenter proxy; your own proxy links are used as given.

## Actor input object example

```json
{
  "makeModels": [
    "Toyota RAV4"
  ],
  "vehicleType": "car",
  "provinces": [
    "ON"
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `report` (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 = {
    "makeModels": [
        "Toyota RAV4"
    ],
    "vehicleType": "car",
    "provinces": [
        "ON"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/autotrader-ca-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 = {
    "makeModels": ["Toyota RAV4"],
    "vehicleType": "car",
    "provinces": ["ON"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/autotrader-ca-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 '{
  "makeModels": [
    "Toyota RAV4"
  ],
  "vehicleType": "car",
  "provinces": [
    "ON"
  ],
  "maxItems": 20
}' |
apify call automation_craft/autotrader-ca-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/autotrader-ca-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/JvA3LD2DCf27yIxoG/builds/0r7b7HezUvbZ938Xy/openapi.json
