# Kijiji.ca Scraper (`haketa/kijiji-scraper`) Actor

Kijiji scraper & API (Canada classifieds): search listings by keyword and category and export title, price, description, location, seller, attributes, photos, date and URL. Canada marketplace and resale market data plus seller lead generation — fast, no login.

- **URL**: https://apify.com/haketa/kijiji-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Developer tools, Real estate, Automation
- **Features:** Limited permissions
- **Stats:** 24 total users, 8 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

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

## Kijiji.ca Scraper — Canada Classifieds Data Extractor for Cars, Apartments, Jobs, Services & Marketplace Listings

> **The most complete Kijiji.ca classifieds extraction tool on Apify.** Pull live listings from **Canada's #1 marketplace** — Kijiji — across all five verticals (Autos, Real Estate, Jobs, Services, Buy & Sell) with a vertical-aware structured schema, FSBO vs dealer detection, bilingual EN/FR handling, and pure HTTP performance. Built for resellers, car flippers, rental researchers, recruiters, and brand-monitoring teams across Toronto, Montreal, Vancouver, Calgary, Ottawa and every Canadian metro.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue?style=for-the-badge)](https://apify.com/haketa/kijiji-scraper)
[![Live Data](https://img.shields.io/badge/Data-Live_at_Run-orange?style=for-the-badge)]()
[![Country](https://img.shields.io/badge/Country-Canada-red?style=for-the-badge)]()
[![Verticals](https://img.shields.io/badge/Verticals-Autos_%7C_Realty_%7C_Jobs_%7C_Services_%7C_Marketplace-purple?style=for-the-badge)]()
[![Scale](https://img.shields.io/badge/Pagination-1%2C000%2B_Listings-green?style=for-the-badge)]()
[![Bilingual](https://img.shields.io/badge/Languages-EN_%2B_FR-blueviolet?style=for-the-badge)]()

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| **🍁 Marketplace Scope** | All 10 Canadian provinces & 3 territories across **5 verticals**: Autos, Real Estate, Jobs, Services, and Buy & Sell |
| **🚗 Vertical-Aware Schema** | 70+ structured fields: VIN, Carfax link, make/model/year/mileage (Autos); bedrooms, bathrooms, rent, utilities, pets (Real Estate); salary & jobType (Jobs) |
| **🏷️ Seller & Price Signals** | Automatic `adSource` detection (`fsbo` private seller vs `dealer` vs `professional`), `priceDropped` flag, `priceOriginal`, `priceClassification`, and `motivatedSeller` |
| **🔢 1,000+ Deep Pagination** | `maxPages: 0` (unlimited default) walks `page-1 → page-2 → page-3…` automatically until your `maxItems` target is reached |
| **🛡️ Deduplication** | 100% deduplicated within every run by canonical `listingId` |
| **📤 Bulk Export** | JSON, CSV, Excel (XLSX), HTML, XML, RSS, and live Apify API / Webhooks |

***

### ✨ What This Kijiji Scraper Does

The **Kijiji.ca Scraper** is a production-ready Apify Actor that extracts **live classified listings** from [**Kijiji.ca**](https://www.kijiji.ca) — the dominant general-purpose marketplace in Canada, owned by Adevinta, with **tens of millions of monthly visits** across English Canada and Quebec. Kijiji is the country's go-to destination for used cars, apartment rentals, household items, freelance services, garage sales, side-hustle jobs, and second-hand everything in every province from Newfoundland to British Columbia.

This actor turns any Kijiji search URL or keyword query into a **clean, structured JSON dataset** — no headless browser, no CAPTCHA solving, no fragile DOM scraping. It uses pure HTTP fetching with intelligent JSON hydration parsing (`__NEXT_DATA__`), automatic vertical detection, and per-vertical schema enrichment so cars come with VIN/mileage/transmission, apartments come with bedrooms/rent/utilities, and services come with hourly-rate and licensed flags — all from the same actor.

In one run you can pull:

- **Autos** — used cars, trucks, motorcycles, ATVs, RVs, boats, snowmobiles, classic cars, heavy equipment
- **Real Estate** — apartments for rent, condos for sale, houses, rooms for rent, vacation rentals, parking spots, land, commercial
- **Jobs** — full-time, part-time, casual, contract, internship, restaurant, healthcare, trades, IT, sales, customer service
- **Services** — moving, cleaning, tutoring, contractors, beauty, automotive repair, pet care, financial, legal
- **Marketplace (Buy & Sell)** — furniture, electronics, baby gear, clothing, sporting goods, tools, musical instruments, free stuff, collectibles

Every listing record includes a normalized price (CAD), location with city + province + lat/long, poster type (FSBO vs dealer/professional), top-ad/showcase flags, full image gallery URLs, and the original Kijiji URL — plus dozens of vertical-specific fields when applicable.

#### 🔎 Why scrape Kijiji.ca yourself when this exists?

Kijiji looks like a "simple" classifieds site, but engineering a stable scraper from scratch surfaces nine annoying problems within the first day:

- Kijiji.ca is a **React/Next.js SPA** — no clean HTML; data is buried inside `<script id="__NEXT_DATA__">` JSON blobs that **change shape periodically** (`results` → `listings` → `mainListings`)
- **Non-standard pagination** — `page-{N}` URL segment inserted in the middle of the path, not a `?page=N` query
- **FSBO vs dealer** distinction lives in the image-CDN URL pattern (`ca-prod-fsbo-ads` vs `ca-prod-dealer-ads`), not an obvious flag — most scrapers miss it entirely
- **Bilingual content** — Quebec listings in French; auto vertical mixes "Berline"/"Sedan", "Manuelle"/"Manual" — requires language detection + normalization
- **Vertical-specific fields** aren't flat: cars have VIN/mileage/Carfax, apartments have bedrooms/utilities/pets, jobs have salary/remote — a generic scraper produces useless lowest-common-denominator rows
- **Moderate anti-bot** — datacenter IPs work intermittently; sustained scraping triggers 403/503 from Akamai. Canadian residential proxies are strongly recommended
- **Top-ads, showcase, highlighted, repost** flags pollute results — without filtering you double-count sponsored items
- **VIP (View Item Page) detail enrichment** requires a second HTTP request per listing with the right Referer header and respectful pacing — or you get throttled

This actor solves all of that: tolerant deep-search JSON parser, vertical-aware extraction, FSBO/dealer CDN detection, EN/FR language handling, page-based pagination, optional VIP enrichment, pacing controls, and full Apify proxy integration with CA residential defaults.

***

### Quick Start

#### One-Click Run

1. Open the [Kijiji.ca Scraper](https://apify.com/haketa/kijiji-scraper) on the Apify Store and click **"Try for free"**
2. Paste a Kijiji search URL — for example `https://www.kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272`
3. Hit **Start** — listings stream into the dataset within seconds
4. Download as JSON, CSV, Excel, HTML, XML, or RSS directly from the dataset view

#### API Run (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/kijiji-scraper").call(run_input={
    "searchUrls": [
        "https://www.kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272",
        "https://www.kijiji.ca/b-apartments-condos/city-of-toronto/c37l1700273"
    ],
    "adSourceFilter": "fsbo-only",
    "fetchDetails": True,
    "maxItems": 200,
    "maxPages": 5
})

for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(listing["title"], "—", listing["priceAmount"], "CAD —", listing["locationCity"])
```

#### API Run (Node.js / TypeScript)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/kijiji-scraper').call({
    keyword: 'toyota corolla',
    categoryCode: 'c174',
    provinces: ['ON', 'QC'],
    minPrice: 5000,
    maxPrice: 15000,
    sortBy: 'priceAsc',
    adSourceFilter: 'fsbo-only',
    maxItems: 500,
    fetchDetails: true
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} private-seller Corollas across ON + QC`);
```

#### API Run (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~kijiji-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchUrls": ["https://www.kijiji.ca/b-apartments-condos/city-of-montreal/c37l1700281"],
    "fetchDetails": true,
    "maxItems": 100,
    "maxPages": 3
  }'
```

***

### 🔁 How It Works & Pagination

Kijiji.ca is a **React/Next.js application** that hydrates its full listing payload into the page HTML inside a `<script id="__NEXT_DATA__">` JSON blob. This actor exploits that fact instead of fighting it:

1. **HTTP fetch** the search/category URL with `got-scraping` (browser-like headers, TLS fingerprint, automatic redirect handling)
2. **Extract the hydration JSON** — primarily from `__NEXT_DATA__`, with fallbacks to Apollo state and JSON-LD blocks
3. **Deep-search the JSON tree** with tolerant field discovery (handles `results`, `listings`, `mainListings`, `ads`, etc. as Kijiji rotates names)
4. **Detect the vertical** from the category code (`c174` → autos, `c37` → real-estate, `c45` → jobs) or fall back to URL pattern inference
5. **Parse with a vertical-aware extractor** — cars get make/model/year/mileage/VIN/transmission; rentals get bedrooms/rent/utilities/pets; jobs get salary/employment type
6. **Detect FSBO vs dealer** by inspecting image CDN URLs (`ca-prod-fsbo-ads/` = private seller, `ca-prod-dealer-ads/` = professional)
7. **Optionally visit each VIP** (View Item Page) for full description, complete image gallery, VIN, Carfax link, amenities, features
8. **Follow pagination** by injecting `page-{N}` into the URL path (Kijiji's idiosyncratic structure) up to your `maxPages` limit

#### Source URL structure

| Page Type | URL Pattern | Example |
|---|---|---|
| Category search | `kijiji.ca/b-{category}/{location}/c{X}l{Y}` | `kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272` |
| Paginated | `kijiji.ca/b-{category}/{location}/page-{N}/c{X}l{Y}` | `kijiji.ca/b-apartments-condos/city-of-toronto/page-3/c37l1700273` |
| Listing detail (VIP) | `kijiji.ca/v-{category}/{city}/{slug}/{listingId}` | `kijiji.ca/v-cars-trucks/toronto/2018-honda-civic-touring/1234567890` |

#### Engineering details

- **Pure HTTP** — no Puppeteer, Playwright, Chromium, or `xvfb`. Single Node process; tiny memory footprint
- **Tolerant JSON parser** survives Kijiji's quarterly schema rotations via deep recursive field discovery
- **Vertical inference** — explicit category-code map + URL-pattern fallback (`/b-cars-trucks/`, `/b-apartments-condos/`, `/b-services/`)
- **FSBO/dealer detection** via image-CDN URL pattern matching (`ca-prod-fsbo-ads` vs `ca-prod-dealer-ads` vs `ca-prod-pro-ads`)
- **Bilingual EN/FR** language detection on description; province-aware (QC defaults to FR scoring boost)
- **Price normalization** — handles `$1,200/mo`, `$15 000`, `Gratuit`, `Please contact`, `Swap/Trade`, `Free` into a clean numeric CAD value
- **Anti-bot pacing** — configurable `requestDelay` + `maxConcurrency` (default 500 ms / 3 parallel); Canadian residential proxy default
- **Price-drop signal** — `priceDropped: true` is emitted when Kijiji flags a reduced price (42% of listings on the verified run). Fields `isRepost`, `underpricedFlag` and `categoryMedian` are reserved placeholders (always `null` today) for a planned cross-run intelligence layer — they are safe to ignore for now.

#### 🔁 Pagination & scale

Kijiji paginates with a `page-{N}` segment injected into the middle of the URL path (not a `?page=N` query), so the actor rewrites each result URL as it walks forward: `page-1 → page-2 → page-3 …` up to your `maxPages` limit, stopping early when a page returns no new listings or the `maxItems` budget is reached. Every record is de-duplicated on `listingId` within the run.

- **Verified behaviour:** a single Cars & Trucks / Ontario run returned **400 unique listings across 9 result pages in ~53 seconds with 0 duplicates** before hitting the `maxItems: 400` cap — roughly 34-46 listings per page.
- **Controls:** `maxItems` caps the total listings across all searches (`0` = unlimited); `maxPages` caps pages per search. Combine with multiple `provinces` or multiple `searchUrls` to fan out — each search is paginated independently, then merged and de-duplicated.
- **Scale:** heavy configurations comfortably pull thousands of listings per run; raise `maxConcurrency` (sweet-spot 5-8 on residential) and `maxPages` to go bigger, or schedule tight filtered runs for near-real-time monitoring.

***

### 📥 Input Parameters

You don't need any URLs or codes to start — just pick a **Category** and **Province** and click **Start**. Power users can paste exact Kijiji result-page URLs into `searchUrls` instead. There is **no `mode` switch** anymore: the actor auto-detects the path (Start URLs if you provide them, otherwise it builds search URLs from your Category/Province pickers), and it auto-detects the vertical from the category code / URL slug.

```json
{
  "keyword": "",
  "categoryCode": "c174",
  "provinces": ["ON"],
  "sortBy": "dateDesc",
  "adSourceFilter": "all",
  "language": "both",
  "minPrice": 0,
  "maxPrice": 0,
  "fetchDetails": false,
  "maxItems": 400,
  "maxPages": 25,
  "searchUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "CA"
  },
  "requestDelay": 500, "maxConcurrency": 3, "maxRetries": 3, "debugMode": false
}
```

#### Parameter reference

| Parameter | Type | Default | Description |
|---|---|---|---|
| `keyword` | `string` | `""` | Free-text search term (e.g. `macbook pro`, `2 bedroom apartment`, `toyota camry`). Leave empty to browse a whole category. Combined with the Category + Province below. |
| `categoryCode` | `string` | `""` | Kijiji category to search (e.g. `c174` cars-trucks, `c37` apartments-condos, `c35` houses-for-sale, `c10` buy-and-sell, `c30` motorcycles, `c45` jobs, `c72` services, `c111` pets). Empty = all categories. |
| `provinces` | `array<string>` | `[]` | One or more Canadian province codes: `ON`, `QC`, `BC`, `AB`, `MB`, `SK`, `NS`, `NB`, `NL`, `PE`, `YT`, `NT`, `NU`. Empty = all of Canada. |
| `sortBy` | `string` | `dateDesc` | Result ordering: `relevance`, `dateDesc` (newest), `priceAsc` (cheapest), `priceDesc` (most expensive). |
| `adSourceFilter` | `string` | `all` | `all` keeps everything. `fsbo-only` = For Sale By Owner (private sellers, ideal for flippers/bargain-hunting). `dealer-only` = professional/dealer listings. `exclude-ebay` = drop eBay cross-listings. |
| `language` | `string` | `both` | Filter by detected description language: `both`, `en` (English only), `fr` (French only). Quebec listings are typically French. |
| `minPrice` | `integer` | `0` | Minimum price in CAD. `0` = no minimum. |
| `maxPrice` | `integer` | `0` | Maximum price in CAD. `0` = no maximum. |
| `fetchDetails` | `boolean` | `false` | Visit each listing's detail page (VIP) for full description, all images, VIN, features, amenities. Slower but much richer. |
| `maxItems` | `integer` | `0` | Max total listings to scrape across all searches. `0` = unlimited (the Console prefills `100` as a fast starting value; set `1000`+ for deep harvests). |
| `maxPages` | `integer` | `0` | Max result pages per search (`0` = unlimited, governed by `maxItems`). Each page returns ~20-40 listings. |
| `searchUrls` | `array<string>` | `[]` | **Advanced:** paste exact Kijiji.ca result-page URLs to scrape them directly. Overrides the Category/Province pickers above. Example: `https://www.kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272`. |
| `proxyConfiguration` | `object` | CA residential | Defaults to Apify RESIDENTIAL group, country `CA`. Strongly recommended for the best coverage and reliability. |
| `requestDelay` / `maxConcurrency` / `maxRetries` | `integer` | `500` / `3` / `3` | Pacing knobs. Kijiji tolerates 3-8 parallel; 500 ms delay; retries on 403/503/429/5xx with backoff. |
| `debugMode` | `boolean` | `false` | Verbose parser logging — dumps hydration JSON for the first page of each search. Useful when Kijiji changes page structure. |

> **Legacy note:** older saved inputs may still contain `mode` and `vertical` — these are ignored and kept only for backwards compatibility. The actor now auto-detects the run path (Start URLs vs pickers) and the vertical (from the category code / URL slug).

***

### 📤 Output Schema

Every listing returns the same flat JSON shape, with vertical-specific fields populated only when relevant. Generic fields apply to every listing; vertical fields populate only for that vertical (e.g. `bedrooms` is `null` for car listings).

#### Common fields (every listing)

| Field | Type | Description |
|---|---|---|
| `listingId` | `string` | Kijiji-internal listing identifier (numeric ID in the URL) |
| `vertical` | `string` | One of `autos`, `real-estate`, `jobs`, `services`, `marketplace` |
| `category` / `categoryCode` / `subCategory` | `string` | Human-readable category, Kijiji code (`c174`, `c37`), and sub-category |
| `title` / `description` / `descriptionLang` | `string` | Title, body (full when `fetchDetails: true`), detected language `en` or `fr` |
| `url` / `searchUrl` | `string` | Canonical listing URL + source search URL it was found through |
| `priceRaw` / `priceAmount` / `priceCurrency` / `priceType` / `isNegotiable` | mixed | Original string, numeric CAD value (`null` for "Please contact"/"Swap"), currency (`CAD`), type (`fixed`, `contact`, `swap`, `free`), OBO/firm flag |
| `priceOriginal` / `priceClassification` | mixed | Original (pre-drop) price in CAD when the listing was reduced, and Kijiji's own price-rating badge (`GREAT`, `GOOD`, `FAIR`). Present mainly on autos listings that carry a reduced price or a price rating. |
| `locationRaw` / `locationCity` / `locationProvince` / `locationId` | `string` | Raw, parsed city, two-letter province (`ON`, `QC`, `BC`...), Kijiji location code (`l9004`...) |
| `latitude` / `longitude` | `number` | Geo coordinates when published (100% on the verified autos run) |
| `adSource` | `string` | `fsbo` (private seller), `dealer`, `professional`, or `ebay` — derived from the image CDN path; `null` if undetermined |
| `posterId` / `posterName` / `posterType` | `string` | `posterId` is always present (e.g. `COMMERCIAL_8040` for dealers); `posterType` is `Verified` when the seller is a verified account. `posterName` and `phoneNumber` are only published on the detail (VIP) page, not search results. |
| `isTopAd` / `isShowcase` / `isHighlighted` | `boolean` | Paid placement flags (top-ad, showcase, highlighted) |
| `activationDate` / `sortingDate` / `scrapedAt` | `string` | ISO-8601 timestamps for first-posted, sort/bump order, and extraction time |
| `imageCount` / `thumbnailUrl` / `imageUrls` | mixed | Photo count, primary thumbnail, and full gallery URLs (resolved to the `kijijica-960-jpg` CDN size) |
| `hasPhone` / `phoneNumber` | mixed | Phone availability flag + value when the poster published it (value on VIP pages) |
| `isRepost` / `priceDropped` | `boolean` | Re-post flag; `priceDropped` is `true` when Kijiji flags a price reduction (42% of the verified run) |

#### Vertical-specific fields

**Autos** (`make`, `model`, `trim`, `year`, `mileageKm`, `transmission`, `fuelType`, `drivetrain`, `bodyType`, `color`, `condition`, `seats`, `doors`, `vin`, `carfaxLink`, `forSaleBy`, `dealerName`, `features[]`, `motivatedSeller`) — covers Cars, Trucks, Motorcycles, RVs, Boats, ATVs. On the verified run: `make`/`model`/`year`/`mileageKm`/`bodyType`/`forSaleBy` 100%, `fuelType` 88%, `drivetrain` 87%, `color` 86%, `trim` 84%, `vin` 74%, `carfaxLink` present on dealer autos that attached a report. `motivatedSeller` matches phrases like "must sell", "moving", "quick sale", "déménagement". `dealerName` is populated only on detail (VIP) pages. (`underpricedFlag`/`categoryMedian` are reserved placeholders — always `null` today.)

**Real Estate** (`listingType`, `propertyType`, `bedrooms`, `bathrooms`, `rentMonthly`, `utilitiesIncluded[]`, `furnished`, `petsAllowed`, `parkingType`, `sizeText`, `availableDate`, `agreementType`, `buildingAmenities[]`, `managementCompany`) — covers apartments, condos, houses, rooms, sublets, short-term, parking, commercial. `bedrooms` enum: `Bachelor/Studio`, `1`, `2`, `3`, `4`, `5+`.

**Jobs** (`jobTitle`, `company`, `jobType`, `salaryRaw`, `salaryMin`, `salaryMax`, `remote`) — `jobType` enum: `Full-time`, `Part-time`, `Contract`, `Casual`, `Internship`, `Seasonal`. `remote` enum: `On-site`, `Hybrid`, `Remote`.

**Services** (`serviceType`, `serviceProvider`, `serviceArea`, `hourlyRate`, `isLicensed`) — covers moving, cleaning, tutoring, beauty, automotive, pet care, financial, legal.

**Marketplace / Buy & Sell** (`itemCondition`, `brand`, `isFirmPrice`, `swapAvailable`, `deliveryAvailable`) — `itemCondition` enum: `New`, `Used`, `Used - Like New`, `Refurbished`, `For Parts`.

#### Example records

**Car listing (dealer, Markham ON — real fields from the verification run):**

```json
{
  "listingId": "1738554114", "categoryCode": "c174",
  "title": "2018 Nissan Qashqai FWD S -NO ACCIDENT-LOW KM-KEYLESS ENTRY-", "descriptionLang": "en",
  "url": "https://www.kijiji.ca/v-cars-trucks/markham-york-region/2018-nissan-qashqai-fwd-s/1738554114",
  "priceRaw": "$11,998", "priceAmount": 11998, "priceCurrency": "CAD", "priceType": "fixed",
  "priceOriginal": null, "priceClassification": "GREAT", "isNegotiable": null,
  "locationCity": "Markham", "locationProvince": "ON", "latitude": 43.8082102, "longitude": -79.4904253,
  "adSource": "dealer", "posterId": "COMMERCIAL_24687", "forSaleBy": "Dealer",
  "make": "nissan", "model": "qashqai", "trim": "FWD S", "year": 2018, "mileageKm": 63360,
  "transmission": "Automatic", "fuelType": "Gasoline", "drivetrain": "FWD", "bodyType": "SUV / Crossover",
  "color": "black", "vin": "JN1BJ1CP1JW156036",
  "carfaxLink": "https://vhr.carfax.ca/?id=OxPxawpypqjOsc50gYgRRp8g11Mjpcv6",
  "features": ["Bluetooth", "Navigation", "Alloy Wheels", "Parking Assist"],
  "isTopAd": true, "isShowcase": true, "priceDropped": false,
  "imageCount": 28, "thumbnailUrl": "https://media.kijiji.ca/api/v1/ca-prod-dealer-ads/images/83/838e...?rule=kijijica-960-jpg",
  "sortingDate": "2026-11-01T00:09:51.000Z", "scrapedAt": "2026-11-01T23:30:19.618Z"
}
```

> Values like `make`/`model`/`color` come straight from Kijiji's canonical attribute values and are lower-cased (e.g. `nissan`, `qashqai`, `black`). `carfaxLink` populates directly from the search results when the seller attached a CARFAX report (26 of 46 dealer autos on page 1 of the verification run). `posterName` and `phoneNumber` only appear when you enable `fetchDetails: true`.

**Apartment rental (Montreal, French):**

```json
{
  "listingId": "1700987654", "categoryCode": "c37",
  "title": "Beau 4½ rénové — Plateau Mont-Royal — Disponible 1er juillet", "descriptionLang": "fr",
  "url": "https://www.kijiji.ca/v-apartments-condos/ville-de-montreal/4-renove-plateau/1700987654",
  "priceRaw": "1 850 $", "priceAmount": 1850, "priceCurrency": "CAD",
  "locationCity": "Montreal", "locationProvince": "QC",
  "adSource": "fsbo", "listingType": "For Rent", "propertyType": "Apartment",
  "bedrooms": "2", "bathrooms": "1", "rentMonthly": 1850,
  "utilitiesIncluded": ["Heat", "Hot water"], "furnished": "No", "petsAllowed": "Limited",
  "sizeText": "750 sqft", "availableDate": "2026-07-01", "buildingAmenities": ["Laundry"],
  "imageCount": 9, "scrapedAt": "2026-05-16T12:00:00.000Z"
}
```

***

### Category & Vertical Reference

#### Top Kijiji vertical → category code map

| Vertical | Category Codes | Coverage |
|---|---|---|
| Autos | `c27` (root), `c174` cars/trucks, `c30` motorcycles, `c171` RVs, `c172` ATVs/snowmobiles, `c173` boats, `c175` parts | Cars, trucks, SUVs, bikes, powersports, marine, parts |
| Real Estate | `c34` (root), `c37` apartments-rent, `c35` houses-sale, `c643` rooms/roommates, `c785` short-term | Rentals, sales, rooms, vacation rentals |
| Marketplace | `c10` Buy & Sell (root) | Furniture, electronics, baby gear, clothing, tools, free stuff |
| Jobs | `c45` Jobs (root) | Full-time, part-time, casual, contract, internship |
| Services | `c72` Services (root) | Moving, cleaning, tutoring, beauty, automotive |

#### Ad source values and price types

| Enum | Values | Notes |
|---|---|---|
| `adSource` | `fsbo` (private seller via `ca-prod-fsbo-ads` CDN), `dealer` (licensed auto dealer), `professional` (other professional), `ebay` (cross-posted from eBay Canada), or `null` (undetermined) | Best filter for flippers (`fsbo-only`) vs B2B (`dealer-only`). On the verified run the split was 128 FSBO / 272 dealer. |
| `priceType` | `fixed` (numeric), `contact` (no number disclosed — "Please Contact"), `swap` (swap/trade only), `free` (`À donner` / "Free") | When `priceType != "fixed"`, `priceAmount` will be `null`. Separate `isNegotiable` boolean captures OBO (`true`) vs firm (`false`). |

***

### 🎯 Use Cases

#### Reseller Arbitrage & Flipping

Power-resellers and side-hustle flippers use Kijiji data to spot mispriced items every morning before competitors:

- **Pull all FSBO furniture/electronics under $200** in your metro with `adSourceFilter: "fsbo-only"` and `maxPrice: 200`
- **Spot price drops** instantly via `priceDropped: true` and compare `priceAmount` against `priceOriginal` for reduced listings
- **Watch for `motivatedSeller` language** (`must sell`, `moving`, `quick sale`, `déménagement`) to time low-ball offers
- **Diff today vs yesterday** to catch newly-listed items in the first hour, when private-seller deals still exist
- **Cross-reference with eBay, Facebook Marketplace, OfferUp** to identify items priced 30%+ below comparable platforms

#### Used-Car Dealers & Auto Flippers

Independent dealers, wholesalers, and auction buyers use the autos vertical for live market intelligence:

- **Aggregate every FSBO Civic/Camry/F-150** across Toronto, Mississauga, Hamilton, Ottawa — the daily wholesale acquisition pool
- **Track dealer competitor inventory** with `adSourceFilter: "dealer-only"` — see who is listing what, at what price
- **Monitor mileage/price distributions** by make/model/year for accurate appraisal benchmarks
- **Pipe Carfax links and flag salvage/rebuilt titles** via the `carfaxLink` and `condition` fields for risk-aware sourcing

#### Real Estate, Rental & Property Research

Renters, landlords, PropTech analysts, and immigration relocation consultants use Kijiji for ground-truth rental data:

- **Build a live rent index** for Toronto, Montreal, Vancouver, Calgary by `bedrooms` and `propertyType`
- **Map utilities-included rentals** vs hydro-extra (huge cost difference in Ontario apartments)
- **Track pets-allowed inventory** for relocators with pets — a chronic Canadian rental pain point
- **Spot new-build supply** by tracking `managementCompany` and `buildingAmenities` arrays
- **Cross-promote with our [Realtor.ca scraper](https://apify.com/haketa/realtor-ca-scraper)** for the for-sale side of the Canadian market

#### Brand & Counterfeit Monitoring

Brand-protection teams at consumer-electronics, fashion, sporting-goods, and beauty companies monitor Kijiji for unauthorised resale:

- **Track listings mentioning your brand** across all five verticals daily
- **Detect unauthorized refurbishers, grey-market dealers, suspiciously-priced "new in box" inventory**
- **Capture poster IDs** to identify repeat offenders (one `posterId` listing 200+ of your products is a red flag)
- **Document evidence with full image galleries** for takedown notices

#### Immigration & Relocation Services

Newcomer-services agencies, settlement workers, and relocation consultants advise on Canadian living costs using fresh Kijiji data:

- **Generate up-to-date "cost of living" briefings** with median rents, used-car prices, furniture costs by metro
- **Build neighbourhood comparison reports** (Plateau vs Verdun, Yorkville vs Liberty Village, Kitsilano vs Mount Pleasant)
- **Help newcomers source affordable household setup** — from beds and dishes to bicycles and winter tires
- **Identify French-only listings** in Quebec for francophone newcomers (`language: "fr"`)
- **Monitor sublet & roommate listings** (`categoryCode: "c643"`) for short-term arrivals

#### Market Research & Retail Strategy

Retailers, CPG brands, and market researchers use second-hand pricing as a leading indicator:

- **Resale price index** for high-ticket items (mattresses, fridges, sofas, e-bikes) — measures real-world depreciation
- **Trend detection** — sudden spike in "Peloton for sale" listings predicts retail demand collapse
- **Inflation tracking** — used-good prices respond faster than retail; great proxy for household discretionary spending
- **Geo-pricing analytics** — same product, different price in Calgary vs Halifax, reveals regional purchasing power

#### Recruiting, Services & Workforce Intelligence

Recruiters, home-services aggregators, gig-economy operators, and insurers mine the jobs + services verticals:

- **Find side-hustle, casual, weekend, and under-the-table roles** that LinkedIn and Indeed never surface
- **Map blue-collar and trades demand** by metro (electricians, drivers, restaurant staff, caregivers, movers)
- **Hourly-rate benchmarking** for trades, cleaning, beauty, and tutoring via the `hourlyRate` field
- **Identify licensed vs unlicensed providers** via `isLicensed` for compliance research

#### Journalism, Public Interest & Academic Research

Journalists at the Globe and Mail, CBC, Toronto Star, Le Devoir, and academic researchers use Kijiji data to report on:

- **Housing affordability crises** — Vancouver rentals over $3,000, Toronto bachelors over $1,800
- **Rental discrimination** — pet/income/family-status language patterns across listings
- **Used-vehicle market shifts** — EV resale, post-pandemic SUV demand
- **Cost-of-living comparisons** across Canadian regions for explanatory journalism

#### Insurance & Risk Underwriting

Auto and property insurers correlate Kijiji data with policy risk:

- **Detect "for sale" vehicles** still appearing on policies (insurance fraud / lapse risk)
- **Benchmark replacement values** for total-loss claims using live FSBO prices
- **Identify rental properties** misclassified on homeowner policies
- **Monitor stolen-goods aggregation patterns** for cargo / commercial property recoveries

***

### 💡 Sample Queries & Recipes

#### Recipe 1: Every FSBO Honda Civic 2015-2019 under $18K across Ontario

```json
{ "keyword": "honda civic", "categoryCode": "c174",
  "provinces": ["ON"], "minPrice": 5000, "maxPrice": 18000,
  "sortBy": "priceAsc", "adSourceFilter": "fsbo-only", "fetchDetails": true, "maxItems": 500 }
```

#### Recipe 2: All 2-bedroom apartments under $2,200 in Montreal

```json
{ "searchUrls": ["https://www.kijiji.ca/b-apartments-condos/city-of-montreal/c37l1700281"],
  "maxPrice": 2200, "language": "both",
  "fetchDetails": true, "maxPages": 10 }
```

#### Recipe 3: Newest Vancouver Buy & Sell listings under $100

```json
{ "searchUrls": ["https://www.kijiji.ca/b-buy-sell/city-of-vancouver/c10l1700287"],
  "maxPrice": 100, "sortBy": "dateDesc",
  "maxItems": 200, "maxPages": 5 }
```

#### Recipe 4: Dealer truck inventory in GTA (sales prospecting)

```json
{ "searchUrls": ["https://www.kijiji.ca/b-cars-trucks/gta-greater-toronto-area/truck/c174l1700272"],
  "adSourceFilter": "dealer-only",
  "fetchDetails": true, "maxItems": 1000, "maxPages": 25 }
```

#### Recipe 5: French-only jobs in Quebec City (immigration / market research)

```json
{ "searchUrls": ["https://www.kijiji.ca/b-emploi/ville-de-quebec/c45l1700124"], "language": "fr", "fetchDetails": true, "maxItems": 300 }
```

#### Recipe 6: Calgary movers — hourly rate benchmarking

```json
{ "searchUrls": ["https://www.kijiji.ca/b-moving-storage/calgary/c105l1700199"], "fetchDetails": true, "maxItems": 100 }
```

#### Recipe 7: Test sample — 25 listings before committing to a full scrape

```json
{ "searchUrls": ["https://www.kijiji.ca/b-cars-trucks/canada/c174l0"], "maxItems": 25, "maxPages": 1 }
```

***

### Integration Examples

#### Google Sheets

Apify schedule + the **"Export to Google Sheets"** integration delivers a fresh Kijiji dataset to your Sheet every morning — perfect for reseller daily-scan workflows.

#### Make.com / Zapier / n8n

Use the **Apify** connector on any major automation platform. Common triggers: new FSBO listings under $X in your category (alert to Telegram/Slack/SMS), price drops (`priceDropped: true`), dealer competitor adding inventory (auto-CRM record), French Quebec listing spike in a category.

#### Power BI / Tableau / Looker

Hook the Apify dataset API as a live data source. Common dashboards: used-car median price heat map by metro and make, rent affordability index across provinces, FSBO vs dealer mix by vertical and city, top-poster leaderboard for brand-monitoring, listing churn rate per category per week.

#### Postgres / Snowflake / BigQuery

Use Apify's [webhook integration](https://docs.apify.com/platform/integrations/webhooks) to POST run results into your warehouse staging tables — clean upsert keyed on `listingId`.

#### CRM Enrichment (Salesforce / HubSpot) and Telegram/Discord Bots

Nightly job pulls every dealer/service-provider listing, dedupes on `posterId`, and upserts as Lead records — Canadian sales-prospect list refreshed daily. For real-time reseller alerts, schedule the actor every 15 minutes with a tight filter (FSBO + max price + city) and POST new `listingId`s to a Telegram bot via Apify webhook.

***

### Major Canadian Markets at a Glance

| Metro Area | Province | Population | Kijiji Significance |
|---|---|---|---|
| Toronto / GTA | ON | 6.6M | Highest listing volume nationally — every vertical |
| Montreal | QC | 4.3M | Largest French-language vertical, strong rentals + autos |
| Vancouver | BC | 2.6M | Highest used-car and rental prices in Canada |
| Calgary | AB | 1.6M | Strong auto vertical (trucks, RVs, oilfield equipment) |
| Edmonton | AB | 1.5M | Heavy trades-services demand, strong buy-and-sell |
| Ottawa | ON | 1.5M | Federal-employee rentals; bilingual EN/FR mix |
| Quebec City | QC | 0.85M | French-only rental and jobs market |
| Winnipeg | MB | 0.83M | High-volume buy & sell, low average prices |
| Hamilton / Mississauga | ON | 1.5M combined | GTA spillover rentals, heavy newcomer demand |
| Kitchener-Waterloo / London | ON | 1.1M combined | Tech-driven rentals, affordable used-car markets |
| Halifax / Victoria / Saskatoon / Regina | NS / BC / SK | 1.4M combined | Maritime, Island, Prairies vertical mix |

#### Top Kijiji search-URL locations (location IDs)

| Location | Code | Use in URL |
|---|---|---|
| All of Canada | `l0` | `kijiji.ca/b-cars-trucks/canada/c174l0` |
| Ontario | `l9004` | `kijiji.ca/b-cars-trucks/ontario/c174l9004` |
| GTA Greater Toronto | `l1700272` | `kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272` |
| City of Toronto | `l1700273` | `kijiji.ca/b-apartments-condos/city-of-toronto/c37l1700273` |
| City of Montreal | `l1700281` | `kijiji.ca/b-apartments-condos/city-of-montreal/c37l1700281` |
| Vancouver | `l1700287` | `kijiji.ca/b-buy-sell/city-of-vancouver/c10l1700287` |
| Calgary | `l1700199` | `kijiji.ca/b-cars-trucks/calgary/c174l1700199` |
| Quebec City | `l1700124` | `kijiji.ca/b-emploi/ville-de-quebec/c45l1700124` |
| Edmonton | `l1700203` | `kijiji.ca/b-cars-trucks/edmonton/c174l1700203` |
| Ottawa | `l1700185` | `kijiji.ca/b-apartments-condos/ottawa/c37l1700185` |

***

### ⚙️ Cost & Performance

| Metric | Value |
|---|---|
| Engine | Pure HTTP + `__NEXT_DATA__` / Apollo JSON hydration parse (no browser) |
| Runtime (measured) | **400 autos listings in ~53 s** on CA residential proxy (search-only). ~15-30 s for 50; 2-4 min for 500; add proportional time with `fetchDetails: true` (one extra HTTP request per listing) |
| Pricing model | Pay-per-event (transparent per-listing pricing) |
| Data freshness | Live at run time |
| Auth required | None |
| Proxy | Recommended — Apify RESIDENTIAL CA by default; datacenter works partially |
| Concurrency | 1-10 parallel (default 3, sweet-spot 5-8 with residential proxy) |
| Memory footprint | 256-512 MB for most runs; 2048 MB headroom for large multi-vertical jobs |

***

### ❓ Frequently Asked Questions

#### How fresh is the data?

**Live at run time.** Every run fetches Kijiji.ca's current listing pages directly — there is no cached intermediate database. A listing that goes up two minutes before your run will appear in the dataset.

#### How many records will I get per run?

Depends entirely on your inputs. A single search page returns 20-40 listings; pagination scales linearly. Typical configurations: 100-2,000 listings per run. Heavy-duty configurations can pull 10,000+ per run with sufficient `maxItems`, `maxPages`, proxy concurrency, and runtime.

#### Does this scraper require a Kijiji account or API key?

No. Kijiji's public listing pages are scraped without login. You only need an Apify account to run the actor.

#### Does Kijiji rate-limit or block scraping?

Yes — moderate anti-bot via Akamai. Datacenter IPs work intermittently. The actor's default config uses Apify's **Canadian residential proxy** group with conservative concurrency (3 parallel) and 500 ms delays — this is sustainable for thousands of listings per run.

#### How do I get the URL for my search?

Open kijiji.ca in your browser, run the search (category, location, filters), and copy the URL from the address bar. Paste into `searchUrls`. The actor preserves all of your category, location, and filter parameters.

#### Does this work for Quebec / French listings?

Yes. The actor handles French listings natively — French price formats (`1 200 $`), French location names (`Ville de Québec`, `Saguenay`), French descriptions. Use `language: "fr"` to filter to French-only or `language: "both"` for full coverage.

#### Can it scrape detail (VIP) pages with full descriptions and image galleries?

Yes — set `fetchDetails: true`. The actor will visit each listing's VIP page for full description, complete image gallery, VIN/Carfax (autos), full amenities (real estate), and feature lists. Runtime increases proportionally because of the extra HTTP request per listing.

#### How does FSBO vs dealer detection work?

Kijiji serves listing images from different CDN paths depending on poster type: `media.kijiji.ca/api/v1/ca-prod-fsbo-ads/` for private sellers, `ca-prod-dealer-ads/` for dealers, `ca-prod-pro-ads/` for other professionals. The actor inspects image URLs to set `adSource`. Use `adSourceFilter: "fsbo-only"` to keep just private sellers.

#### Can I scrape only listings posted in the last 24 hours, or apply Kijiji's native filters?

Sort with `sortBy: "dateDesc"` and cap `maxPages` low (1-2), then filter downstream on `activationDate`. For built-in Kijiji filters (price, condition, year, mileage), apply them in the UI and paste the resulting URL into `searchUrls` — Kijiji's native filter engine is preserved.

#### How do I export the data and schedule recurring runs?

Standard Apify formats: JSON, CSV, Excel, HTML, XML, RSS, JSON Lines. Apify's built-in Scheduler supports any cron expression — daily 6 AM ET for full inventory, every 15 minutes for hot-deal Telegram alerts, weekly Sunday for market reports.

#### Does the actor deduplicate?

Yes — within a single run, listings are deduped by `listingId`. Across runs, persist `listingId` to your warehouse and upsert.

#### What happens if Kijiji changes its page structure?

The actor uses a **tolerant deep-search JSON parser** that survives most schema rotations (`results` → `mainListings` → `listings`). For larger changes, enable `debugMode: true` and the actor dumps the full hydration JSON structure so you (or we) can patch field discovery.

#### Does it work on the Apify Free Plan?

Yes — full functionality on the free tier. A 50-100 listing test run completes in well under a minute and costs a tiny fraction of free monthly credits.

#### Does this scrape Kijiji Centrale or Kijiji Autos (the new auto-specific portal)?

This actor focuses on the main `kijiji.ca` classifieds. The new Kijiji Autos portal at `kijiji.ca/autos` has overlapping data, but for the cleanest auto-only flow use the standard search URLs under the `c174` category code.

#### Are buyer messages, watchlists, or seller email addresses included?

No. The actor only extracts data Kijiji publishes openly on listing pages. Buyer messages, watchlists, and seller emails are private and never scraped.

#### How does pay-per-event pricing work?

You're charged a small amount per actor start and per listing delivered. No monthly minimums. A 100-listing scrape costs pennies; a 10,000-listing daily job is still well under the cost of comparable paid classifieds APIs.

#### How do I report a bug or request a feature?

Open an issue on the Apify Store actor page or contact the developer through the Apify Console. Include the exact `searchUrls` input that failed plus the run ID — fastest path to a fix.

***

### 🔗 Related Apify Actors by Haketa

If you need classifieds, marketplace, or Canadian property data from other regions, check these companion actors:

- [Realtor.ca Scraper (Canada)](https://apify.com/haketa/realtor-ca-scraper) — Canadian for-sale + for-rent residential properties from Canada's national MLS portal (sibling to Kijiji's real-estate vertical)
- [Kleinanzeigen.de Scraper (Germany)](https://apify.com/haketa/kleinanzeigen-scraper) — Germany's #1 classifieds (formerly eBay Kleinanzeigen)
- [Marktplaats.nl Scraper (Netherlands)](https://apify.com/haketa/marktplaats-scraper) — Netherlands' dominant classifieds marketplace
- [OfferUp Scraper (US)](https://apify.com/haketa/offerup-scraper) — US local-marketplace listings, ideal for cross-border arbitrage
- [TradeMe Scraper (New Zealand)](https://apify.com/haketa/trademe-scraper) — New Zealand's largest classifieds + auction site
- [Lelong.my Scraper (Malaysia)](https://apify.com/haketa/lelong-my-scraper) and [Chotot.com Scraper (Vietnam)](https://apify.com/haketa/chotot-scraper) — Southeast Asian classifieds platforms
- [Mourjan Scraper (MENA)](https://apify.com/haketa/mourjan-scraper) — Middle East / North Africa classifieds
- [Rent.com Scraper](https://apify.com/haketa/rent-com-scraper) and [Apartments.com Scraper](https://apify.com/haketa/apartments-com-scraper) — US apartment rentals for cross-border analytics
- [BBB Business Scraper](https://apify.com/haketa/bbb-scraper) — Better Business Bureau profiles for cross-border business verification

***

### Comparison vs. Alternatives

| Approach | Setup time | Maintenance | Vertical-aware | FSBO/dealer detection | Bilingual EN/FR | Proxy mgmt |
|---|---|---|---|---|---|---|
| **This actor** | < 1 minute | Zero | Built-in (5 verticals) | Built-in via image CDN | Built-in | Built-in (CA residential) |
| Manual Kijiji browsing | Instant | None | Eyeball only | None | None | N/A |
| Custom Python + BeautifulSoup | 4-12 hours | Breaks weekly | DIY | DIY (most miss) | DIY | DIY |
| Custom Puppeteer/Playwright | 2-4 days | High | DIY | DIY | DIY | DIY |
| Paid third-party classifieds API | Hours to onboard | Vendor lock-in | Limited | Sometimes | Rarely | Included |
| Browser-extension scrapers | Minutes | High | None | None | None | None |

***

### Why Pay-Per-Event Pricing?

Most scrapers either lock you into a flat monthly subscription (pay even when idle) or per-Compute-Unit (unpredictable per-run cost). This actor uses **pay-per-event**:

- You only pay when the actor runs and produces results
- Charges scale linearly with how many listings you actually consume
- Transparent line-item billing inside Apify
- No monthly minimums — perfect for ad-hoc reseller flips or seasonal research
- Free to evaluate — sample with `maxItems: 25` for a fraction of a cent
- Combine with Apify's Scheduler to keep daily costs predictable

***

If this actor saves you time, a **5-star rating** on the Apify Store helps other Canadian resellers, dealers, recruiters, brand teams, and PropTech analysts discover it. Thank you!

***

### 📋 Changelog

| Version | Date | Notes |
| :--- | :--- | :--- |
| **1.2.0** | **2026-11** | **Unlocked 1,000+ deep pagination:** changed `maxPages` default from `2` to `0` (unlimited, governed by `maxItems`), removed the `EMPTY_RUN_ITEM_CAP` (`100`) and `EMPTY_RUN_PAGE_CAP` (`2`) clamps when users explicitly pass `maxItems > 100` on default or category searches, and verified multi-page extraction with 0 duplicates. |
| **1.1.0** | **2026-11** | Fixed CARFAX/CARPROOF link extraction (`carprooflink` attribute mapped to `carfaxLink`). Re-verified 400 unique autos listings, 0 duplicates, core fields 93–100%. |
| **1.0.0** | **2026-05** | Initial public release — 5 verticals (autos / real-estate / jobs / services / marketplace), FSBO/dealer detection via image-CDN inspection, bilingual EN/FR handling, vertical-aware schema, and optional VIP detail enrichment. |

# Changelog

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

# Actor input Schema

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

What are you looking for? e.g. 'macbook pro', 'toyota camry', '2 bedroom apartment', 'warehouse jobs'. Leave empty to browse a whole category. Combined with the Category and Province you choose below.

## `categoryCode` (type: `string`):

Pick the section of Kijiji to search. Leave on 'All categories' to search everything.

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

Pick one or more provinces to search. Leave empty to search all of Canada.

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

How results are ordered on Kijiji.

## `adSourceFilter` (type: `string`):

Keep only certain sellers. 'For Sale By Owner' = private sellers (great for flippers and bargains). 'Dealer / Pro' = professional listings. 'Exclude eBay' drops eBay cross-listings.

## `language` (type: `string`):

Keep only listings in a certain language. Quebec listings are usually French.

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

Only keep listings at or above this price. Leave 0 for no minimum.

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

Only keep listings at or below this price. Leave 0 for no maximum.

## `fetchDetails` (type: `boolean`):

Open each listing page for complete data — full description, all photos, VIN, features and amenities. Richer results but slower. Off = fast summary from the results page.

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

Maximum total listings to collect across all searches. Set 0 for unlimited.

## `maxPages` (type: `integer`):

How many result pages to read per search (0 = unlimited, governed by Max Items). Each page returns about 20-40 listings.

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

Advanced: paste exact Kijiji.ca result-page URLs to scrape them directly. This overrides the Category/Province pickers above. Example: 'https://www.kijiji.ca/b-cars-trucks/gta-greater-toronto-area/c174l1700272'. Leave empty to use the simple pickers.

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

Canadian residential proxy is recommended for the best coverage and reliability. Uses Apify Proxy with the RESIDENTIAL group and CA country by default.

## `requestDelay` (type: `integer`):

Delay between requests in milliseconds. Higher values are gentler on the site.

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

Number of parallel requests. Keep lower for the most reliable runs.

## `maxRetries` (type: `integer`):

How many times to retry a failed request.

## `debugMode` (type: `boolean`):

Verbose logging for troubleshooting when Kijiji changes its page structure. Leave off for normal runs.

## Actor input object example

```json
{
  "keyword": "toyota camry",
  "categoryCode": "",
  "provinces": [
    "ON"
  ],
  "sortBy": "dateDesc",
  "adSourceFilter": "all",
  "language": "both",
  "minPrice": 0,
  "maxPrice": 0,
  "fetchDetails": false,
  "maxItems": 100,
  "maxPages": 0,
  "searchUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CA"
  },
  "requestDelay": 500,
  "maxConcurrency": 3,
  "maxRetries": 3,
  "debugMode": false
}
```

# Actor output Schema

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

All extracted Kijiji listings for this run (JSON, CSV, Excel...).

## `overviewTable` (type: `string`):

Clean, human-readable table of the scraped listings.

## `listingId` (type: `string`):

Kijiji 10-digit numeric listing ID

## `vertical` (type: `string`):

marketplace / autos / real-estate / jobs / services

## `category` (type: `string`):

Listing category name

## `categoryCode` (type: `string`):

Kijiji URL category code (c174, c37...)

## `subCategory` (type: `string`):

Sub-category name

## `title` (type: `string`):

Listing title

## `description` (type: `string`):

Full listing description

## `descriptionLang` (type: `string`):

Detected language: en / fr

## `url` (type: `string`):

Full listing URL

## `priceRaw` (type: `string`):

Original price string as shown

## `priceAmount` (type: `string`):

Parsed numeric price in CAD

## `priceCurrency` (type: `string`):

Always CAD

## `priceType` (type: `string`):

fixed / contact / free / swap / negotiable

## `priceOriginal` (type: `string`):

Original (pre-drop) price in CAD when reduced

## `priceClassification` (type: `string`):

Kijiji price badge: GREAT / GOOD / FAIR (autos)

## `isNegotiable` (type: `string`):

OBO / not firm

## `locationRaw` (type: `string`):

Location string as shown

## `locationCity` (type: `string`):

City name

## `locationProvince` (type: `string`):

Province code (ON, QC, BC...)

## `locationId` (type: `string`):

Kijiji URL location code (l1700272...)

## `latitude` (type: `string`):

Latitude coordinate

## `longitude` (type: `string`):

Longitude coordinate

## `adSource` (type: `string`):

fsbo / dealer / professional / ebay

## `posterId` (type: `string`):

Seller internal ID

## `posterName` (type: `string`):

Seller display name

## `posterType` (type: `string`):

Private / Business / Dealer

## `isTopAd` (type: `string`):

Paid top placement

## `isShowcase` (type: `string`):

Paid showcase placement

## `isHighlighted` (type: `string`):

Paid highlighted placement

## `activationDate` (type: `string`):

First publication date

## `sortingDate` (type: `string`):

Last bump/update date

## `imageCount` (type: `string`):

Number of photos

## `thumbnailUrl` (type: `string`):

First image URL

## `imageUrls` (type: `string`):

All photo URLs

## `hasPhone` (type: `string`):

Phone number available

## `phoneNumber` (type: `string`):

Contact phone if shown

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

Vehicle make (autos)

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

Vehicle model (autos)

## `trim` (type: `string`):

Vehicle trim (autos)

## `year` (type: `string`):

Vehicle year (autos)

## `mileageKm` (type: `string`):

Odometer in kilometers (autos)

## `transmission` (type: `string`):

Automatic / Manual (autos)

## `fuelType` (type: `string`):

Gas / Diesel / Hybrid / Electric (autos)

## `drivetrain` (type: `string`):

FWD / RWD / AWD / 4x4 (autos)

## `bodyType` (type: `string`):

Sedan / SUV / Truck (autos)

## `color` (type: `string`):

Exterior color (autos)

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

New / Used / Certified (autos)

## `seats` (type: `string`):

Seat count (autos)

## `doors` (type: `string`):

Door count (autos)

## `vin` (type: `string`):

Vehicle Identification Number (autos)

## `carfaxLink` (type: `string`):

CARFAX/CARPROOF report URL (autos)

## `forSaleBy` (type: `string`):

Owner / Dealer (autos)

## `features` (type: `string`):

Vehicle features list (autos)

## `dealerName` (type: `string`):

Dealership name (autos)

## `listingType` (type: `string`):

For Rent / For Sale / Room (real estate)

## `propertyType` (type: `string`):

Apartment / Condo / House (real estate)

## `bedrooms` (type: `string`):

Bedroom count or Bachelor/Studio (real estate)

## `bathrooms` (type: `string`):

Bathroom count (real estate)

## `rentMonthly` (type: `string`):

Monthly rent in CAD (real estate)

## `utilitiesIncluded` (type: `string`):

Hydro/Heat/Water/Internet (real estate)

## `furnished` (type: `string`):

Furnished / Unfurnished (real estate)

## `petsAllowed` (type: `string`):

Pet policy (real estate)

## `parkingType` (type: `string`):

Street / Driveway / Garage (real estate)

## `sizeText` (type: `string`):

Unit size text e.g. 750 sqft (real estate)

## `availableDate` (type: `string`):

Move-in date (real estate)

## `agreementType` (type: `string`):

1 Year / Month-to-Month (real estate)

## `buildingAmenities` (type: `string`):

Gym/Pool/Laundry/Elevator (real estate)

## `managementCompany` (type: `string`):

Property management company (real estate)

## `jobTitle` (type: `string`):

Position title (jobs)

## `company` (type: `string`):

Employer name (jobs)

## `jobType` (type: `string`):

Full-Time / Part-Time / Contract (jobs)

## `salaryRaw` (type: `string`):

Original salary string (jobs)

## `salaryMin` (type: `string`):

Parsed minimum salary (jobs)

## `salaryMax` (type: `string`):

Parsed maximum salary (jobs)

## `remote` (type: `string`):

On-site / Remote / Hybrid (jobs)

## `serviceType` (type: `string`):

Cleaning / Moving / Tutoring (services)

## `serviceProvider` (type: `string`):

Provider name (services)

## `serviceArea` (type: `string`):

Service coverage area (services)

## `hourlyRate` (type: `string`):

Hourly rate in CAD (services)

## `isLicensed` (type: `string`):

Licensed provider flag (services)

## `itemCondition` (type: `string`):

New / Used / Open Box (marketplace)

## `brand` (type: `string`):

Item brand (marketplace)

## `isFirmPrice` (type: `string`):

Price is firm (marketplace)

## `swapAvailable` (type: `string`):

Will trade/swap (marketplace)

## `deliveryAvailable` (type: `string`):

Pickup / Ship / Deliver (marketplace)

## `isRepost` (type: `string`):

Detected repost of an earlier listing

## `priceDropped` (type: `string`):

Price reduced since first seen

## `underpricedFlag` (type: `string`):

Price below category median threshold

## `categoryMedian` (type: `string`):

Median price for the category in this run

## `motivatedSeller` (type: `string`):

Description signals urgency (must sell etc.)

## `searchUrl` (type: `string`):

Search URL this listing was found through

## `scrapedAt` (type: `string`):

ISO timestamp when scraped

# 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 = {
    "keyword": "toyota camry",
    "provinces": [
        "ON"
    ],
    "maxItems": 100,
    "searchUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "CA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/kijiji-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 = {
    "keyword": "toyota camry",
    "provinces": ["ON"],
    "maxItems": 100,
    "searchUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "CA",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/kijiji-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 '{
  "keyword": "toyota camry",
  "provinces": [
    "ON"
  ],
  "maxItems": 100,
  "searchUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CA"
  }
}' |
apify call haketa/kijiji-scraper --silent --output-dataset

```

## MCP server setup

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