# Kijiji Property Scraper (`sian.agency/kijiji-property-scraper`) Actor

Scrape Kijiji real estate across Canada: apartments, basement suites, rooms, houses and land, for rent or for sale. Price, beds, baths, sqft, utilities, move-in date and whether an owner or an agent posted it.

- **URL**: https://apify.com/sian.agency/kijiji-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.32 / 1,000 listing searches

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Kijiji Property Scraper — Canadian Rentals & Real Estate Data 🍁

[![Store SIÁN Agency](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Store Realtor.ca Property Scraper](https://img.shields.io/badge/Store-Realtor.ca%20Property%20Scraper-D92228)](https://apify.com/sian.agency/realtor-ca-property-scraper?fpr=sian) [![Store Centris.ca Property Scraper](https://img.shields.io/badge/Store-Centris.ca%20Property%20Scraper-1AE392)](https://apify.com/sian.agency/centris-ca-property-scraper?fpr=sian) [![Store Craigslist Scraper](https://img.shields.io/badge/Store-Craigslist%20Scraper-5C2D91)](https://apify.com/sian.agency/craigslist-scraper?fpr=sian)

#### 🍁 Around 22,000 of Kijiji's 48,000 long-term rentals are posted by the owner, not a management company

##### Every row tells you which is which — plus rent, bedrooms, bathrooms, square feet, move-in date and what the rent covers

***

### 🔎 What is the Kijiji Property Scraper — and when should you use it?

The **Kijiji Property Scraper** turns any Kijiji real-estate search in Canada into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Canadian rentals and homes for sale with rent or asking price, bedrooms (dens counted as a half), bathrooms, square feet and unit type. Rows also carry the lease term, move-in date, pet and smoking rules, which utilities the rent covers, amenities, accessibility features, city, neighbourhood, coordinates and photos. Every row states whether an owner or a professional posted the ad, which is the half of the Canadian rental market the brokerage portals never carry. A detail pass adds the untruncated ad text, the view counter and the poster's profile.

**Use something else when:** you need brokerage data rather than classifieds. Use [Realtor.ca Property Scraper](https://apify.com/sian.agency/realtor-ca-property-scraper?fpr=sian) for Canadian MLS listings with brokerage detail and market KPIs. Use [Centris.ca Property Scraper](https://apify.com/sian.agency/centris-ca-property-scraper?fpr=sian) for Quebec brokerage listings and MLS data. This actor covers Kijiji's Canadian real-estate section only — no sold history and no listing-agent data.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/kijiji-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want Canadian property listings from Kijiji, split by who posted them using the Apify Actor `sian.agency/kijiji-property-scraper`.

Use it when I need: Canadian rentals and homes for sale with rent or asking price, bedrooms (dens counted as a half), bathrooms, square feet and unit type. Rows also carry the lease term, move-in date, pet and smoking rules, which utilities the rent covers, amenities, accessibility features, city, neighbourhood, coordinates and photos. Every row states whether an owner or a professional posted the ad, which is the half of the Canadian rental market the brokerage portals never carry. A detail pass adds the untruncated ad text, the view counter and the poster's profile.

Don't use it when: you need brokerage data rather than classifieds — use realtor-ca-property-scraper or centris-ca-property-scraper instead.

How to call it: pick an `operation` — `search` sweeps a Kijiji search, `detail` reads named ads. For a search, either paste addresses into `searchUrls` or build one with `category` and `location`. Categories are 37 long-term rentals, 36 rooms, 35 houses for sale, 643 condos, 641 land, 42 short-term and 40 commercial; location 0 is all of Canada. Narrow with `keywords`, `listedBy` (`owner` or `professional`), `bedrooms`, `minPrice`/`maxPrice` and `sortBy`. Cap the run with `maxItems`, and switch on `enrichWithDetails` for the full ad text, the view count and the poster.

Start with this input:
{
  "operation": "search",
  "category": "37",
  "location": "1700273",
  "listedBy": "owner",
  "maxItems": 100
}

Ask me which Canadian city or province, and whether you want rentals, rooms or property for sale, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull every two-bedroom rental in Toronto posted by an owner under $2,500 and rank them by price per square foot.*
- *Watch Calgary rentals every morning and tell me which ads are new since yesterday.*
- *Compare average asking rent for a one-bedroom across Vancouver, Montreal and Ottawa, split by owner-posted versus agency-posted.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/kijiji-property-scraper.md](https://apify.com/sian.agency/kijiji-property-scraper.md).

### 📋 Overview

**Kijiji is where Canadian landlords post when they do not want an agent.** That is a large slice of the market and it does not appear on the brokerage portals. Twenty-four of the twenty-five Kijiji Actors on the Store scrape cars, sofas and apartments into one shapeless row.

**What you get instead:**

- ✅ **Owner or professional, stated on every row**: Kijiji asks posters to declare it. Around 22,000 of 48,000 long-term rentals say owner. You get `listedBy` and a plain `isPrivateLandlord` flag, filterable before the run or after it.
- 🏘️ **63 typed fields, not a raw attribute dump**: bedrooms with dens split out, bathrooms at the half, square feet, unit type, lease term, move-in date, pet and smoking rules, utilities, amenities, accessibility.
- 🇨🇦 **Every branch of Kijiji real estate**: long-term rentals, short-term rentals, rooms and roommates, storage and parking, commercial space, houses, condos, land. Roughly 243,000 live ads.
- ⚜️ **English and French**: Québec is served under `/b-immobilier/` addresses with the same ids and the same data. A Montréal sweep returns the same columns as a Toronto one.
- 💰 **$1.50 per 1,000 listings**, dropping to $1.32 at the deepest volume tier. Four of the six priced rivals charge more, one of them more than four times as much.
- 🔗 **Paste the search you already built**: set up any filter combination on kijiji.ca, copy the address, and the site resolves it — including facets added after this Actor shipped.

***

### ✨ Features

- 🔍 **Two ways in**: paste Kijiji search addresses, or fill in category, place, keyword, price band and posted-by.
- 👤 **Private-landlord filter**: narrow the run to owner-posted ads before a single row is billed.
- 🛏️ **Real bedroom and bathroom numbers**: Kijiji sends bathrooms multiplied by ten and dens as halves. Both arrive fixed.
- 🔌 **Utilities and amenities as clean lists**: which of hydro, heat, water, cable and internet the rent covers, and what the building has.
- 📅 **Move-in dates and lease terms**: the two fields a renter search actually turns on.
- 🌐 **Coordinates and neighbourhood on every ad**: map it, cluster it, or join it to your own geography.
- 🔬 **Optional depth pass**: opens each ad for the untruncated text, the view counter and the poster's profile.
- 📄 **Read named ads directly**: paste ad addresses or bare numeric ids to re-check listings you already track.
- ⚜️ **Bilingual addresses**: `/b-real-estate/` and `/b-immobilier/` both work and return the same rows.
- 📊 **HTML run report**: every run writes a summary with the listings, the failures and exactly what you were charged.

***

### 🎬 Quick Start

Pick a category and a place, press Start, and the first hundred listings land in your dataset about fifteen seconds later. Nothing to install and no key to configure. When you want a specific slice, build the search on kijiji.ca and paste the address instead.

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~kijiji-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"search","category":"37","location":"1700273","listedBy":"owner","maxItems":100}'
```

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose what to read

Pick a 🗂️ Property category and a 📍 Province or metro. Or open kijiji.ca, filter the search however you like, and paste that address into 🌐 Kijiji search URLs.

#### Step 2: Narrow it, or do not

👤 Posted by, 🛏️ Bedrooms, a price band and 🔢 Maximum results are all optional. Leave them alone and you get the section newest-first.

#### Step 3: Press Start

Results arrive in the dataset as they are found. Export to JSON, CSV or Excel, or read them over the API.

**That's it! In under a minute, you'll have:**

- A structured table of live Canadian listings with prices and property attributes
- The owner-versus-professional split for every one of them
- Map coordinates, photos and a link back to each ad

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|---|---|---|---|
| `operation` | string | No | `search` (default) or `detail` |
| `searchUrls` | array | No | Kijiji search addresses, pasted as-is |
| `keywords` | string | No | Words that must appear in the ad |
| `category` | string | No | Kijiji real-estate category id — `37` is long-term rentals |
| `location` | string | No | Province or metro id — `0` is all of Canada |
| `listedBy` | string | No | `any`, `owner` or `professional` |
| `bedrooms` | string | No | `any`, `0` for a bachelor, up to `5` |
| `minPrice` / `maxPrice` | integer | No | Price band in Canadian dollars, `0` for no bound |
| `sortBy` | string | No | `dateDesc`, `dateAsc`, `priceAsc` or `priceDesc` |
| `maxItems` | integer | No | Cap per search address, up to 5000 |
| `enrichWithDetails` | boolean | No | Open each ad for the full record |
| `listingUrls` | array | No | Ad addresses or bare numeric ids, for `detail` |

**Example — owner-posted two-bedrooms in Toronto under $2,500:**

```json
{
  "operation": "search",
  "category": "37",
  "location": "1700273",
  "listedBy": "owner",
  "bedrooms": "2",
  "maxPrice": 2500,
  "maxItems": 500
}
```

**Example — paste the searches you already use:**

```json
{
  "operation": "search",
  "searchUrls": [
    "https://www.kijiji.ca/b-apartments-condos/city-of-toronto/c37l1700273?for-rent-by=ownr",
    "https://www.kijiji.ca/b-immobilier/grand-montreal/c37l80002"
  ],
  "maxItems": 1000
}
```

**Example — read specific ads:**

```json
{
  "operation": "detail",
  "listingUrls": ["1742889268", "https://www.kijiji.ca/v-apartments-condos/city-of-toronto/main-floor/1742579694"]
}
```

***

### 📤 Output

Every run writes flat rows to the Apify dataset — **63 fields**, all nullable, ready for a spreadsheet or a database. The most useful ones:

| Field | Type | Description |
|---|---|---|
| `listingTitle` | string | The headline the poster wrote |
| `price` | number | Monthly rent or asking price in Canadian dollars |
| `dealType` | string | `rent` or `sale`, from the ad's own category |
| `listedBy` | string | `owner`, `professional` or `agent`, as declared on the ad |
| `isPrivateLandlord` | boolean | `true` when an owner posted it |
| `bedrooms` | number | Dens count as a half — `1.5` is one bedroom plus a den |
| `bathrooms` | number | Whole and half bathrooms |
| `areaSqFt` | number | Floor area in square feet |
| `propertyType` | string | Apartment, Basement apartment, Condo, House, Townhouse, Duplex / triplex |
| `availableFrom` | string | The move-in date the poster gave |
| `utilitiesIncluded` | array | Which of Hydro, Heat, Water, Cable / TV, Internet the rent covers |
| `amenities` | array | Laundry, dishwasher, air conditioning, balcony, yard, gym, pool, elevator and more |
| `petsAllowed` | string | `yes`, `no` or `limited` |
| `city` / `neighbourhood` | string | Where Kijiji files the ad |
| `latitude` / `longitude` | number | Map coordinates |
| `views` | number | How many times the ad has been opened (depth pass) |
| `posterName` | string | The name on the account (depth pass) |
| `imageUrls` | array | Photos — thumbnails on a search row, full resolution on a depth row |

**Example row:**

```json
{
  "itemId": "1742510102",
  "listingTitle": "2Br 1 Bath, House for Rent, Parking & Laundry, Util Included",
  "url": "https://www.kijiji.ca/v-apartments-condos/city-of-toronto/2br-1-bath-house-for-rent/1742510102",
  "price": 2850,
  "priceText": "$2,850",
  "currency": "CAD",
  "dealType": "rent",
  "listedBy": "owner",
  "isPrivateLandlord": true,
  "propertyType": "House",
  "bedrooms": 2,
  "bathrooms": 1,
  "areaSqFt": 972,
  "petsAllowed": "yes",
  "smokingPermitted": "no",
  "parkingSpots": 1,
  "agreementType": "1 year",
  "availableFrom": "2026-10-01T00:00:00Z",
  "utilitiesIncluded": ["Hydro", "Heat", "Water"],
  "amenities": ["Yard", "Laundry in building", "Dishwasher", "Fridge / freezer", "Air conditioning"],
  "city": "East York",
  "neighbourhood": "O'Connor-Parkview",
  "latitude": 43.70719,
  "longitude": -79.31047,
  "categoryName": "Long Term Rentals",
  "postedAt": "2026-08-24T23:36:44.000Z",
  "imageCount": 13
}
```

***

### 💼 Use Cases & Examples

#### 1. Private-Landlord Rental Sourcing

**Relocation services and tenant-placement agencies need the inventory that never reaches a brokerage portal.**

**Input:** category `37`, a metro, 👤 Posted by set to owner
**Output:** owner-posted rentals with rent, rooms, move-in date and what the rent includes
**Use:** build a shortlist for a client in one pass instead of refreshing the site all week

#### 2. Rent Benchmarking by Bedroom Count

**Property managers and analysts setting a price need the real spread, not a headline average.**

**Input:** a city, no price bound, 🔢 Maximum results at 1,000
**Output:** asking rent against bedrooms, bathrooms, square feet and utilities on every row
**Use:** price a unit against the market it actually competes in, and see how much of the gap is bundled utilities

#### 3. New-Listing Monitoring

**Agents and investors who want to be first need to know what appeared overnight.**

**Input:** a saved search, ↕️ Order set to newest first, run on a schedule
**Output:** the posted timestamp on every row, so a diff against yesterday is trivial
**Use:** a daily watch on one neighbourhood costs pennies and lands before the market wakes up

#### 4. Basement Suites, Rooms and Shared Housing

**Student-housing operators and roommate platforms need a market that barely exists anywhere else.**

**Input:** category `36` for rooms and roommates, or unit type filtering on `basement-apartment`
**Output:** 11,000 room ads nationally, plus basement suites named as their own unit type
**Use:** the only reliable read on the shared-housing end of the Canadian market

#### 5. Investor Deal Screening

**Buyers hunting owner-sold property want the ads where the negotiating room is.**

**Input:** category `35` or `643`, a region, a price band
**Output:** asking price against floor area and lot size, with owner or brokerage stated
**Use:** flag private sales in a target region without opening 200 tabs

#### 6. Property-Manager and Agency Lead Lists

**Suppliers selling into property management need to know who is actually active.**

**Input:** commercial or long-term rentals in a region, 🔬 depth on
**Output:** poster name, account type and how many ads they currently carry
**Use:** rank a region's active managers by live inventory instead of guessing

#### 7. Cross-Border and Bilingual Market Research

**Analysts covering Canada need Québec on the same axes as everywhere else.**

**Input:** `/b-immobilier/` addresses, or location `9001` for Québec
**Output:** the same 63 columns, because the fields are machine keys rather than display labels
**Use:** one dataset that covers both official languages without a translation step

***

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/kijiji-property-scraper').call({
  operation: 'search',
  category: '37',
  location: '1700273',
  listedBy: 'owner',
  maxItems: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.bedrooms >= 2).length, 'two-bed-plus owner rentals');
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/kijiji-property-scraper').call(
    run_input={
        'operation': 'search',
        'category': '37',
        'location': '1700199',
        'maxPrice': 2000,
        'maxItems': 500,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['price'], item['bedrooms'], item['city'], item['listedBy'])
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~kijiji-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"search","category":"36","location":"1700272","maxItems":300}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: a daily schedule, or a webhook from your own system
2. **HTTP Request**: call the Actor with your saved search
3. **Process**: filter on `isPrivateLandlord`, `bedrooms` or `price`
4. **Action**: append new ads to a sheet, post them to Slack, or alert on a price drop

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run — every field, every mode, same data
- No credit card required
- Enough to see the columns and decide

#### PAID Tier (Production Ready)

- **Unlimited** listings per run, up to Kijiji's own 5,000-per-search ceiling
- 46 listings per page read, and a page read takes about a second
- Pay per listing returned: a search that matched nothing, an ad that was taken down, and any address we could not read all cost you nothing

💰 **$1.50 per 1,000 listings** at the entry tier, falling to **$1.32** at the deepest volume tier. Of the six priced Kijiji Actors on the Store, four charge more — one charges $6.50.

🔗 [View current pricing](https://apify.com/sian.agency/kijiji-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: How many listings can I get?**
A: FREE tier gives 25 per run. PAID is unlimited per run, and one search reaches about 5,000 listings before Kijiji stops paging. Past that, split the search by city or price band.

**Q: Does it work on French Kijiji addresses?**
A: Yes. Québec is served under `/b-immobilier/` with the same category and location ids, and the same listings come back. Paste either form.

**Q: Can I get a landlord's phone number?**
A: Only what the ad itself shows. Kijiji routes contact through its own inbox and masks most digits, so a depth row returns the masked line when there is one. There is no email on the platform to return.

**Q: Why is the price blank on some rows?**
A: The poster chose "Please Contact" instead of entering a number — about 7% of the board. Those rows carry the words in `priceText` and nothing in `price`, so a numeric filter drops them.

**Q: Does it return sold or rented prices?**
A: No. Ads come down when they go and Kijiji publishes no archive, so you get live asking prices. Build history by running on a schedule and diffing your own snapshots.

**Q: Do I need a proxy or an account?**
A: Neither. These are the pages any visitor sees, so there is no proxy line on your bill and nothing to log in to.

**Q: What output formats are available?**
A: JSON, CSV, Excel and XML, straight from the Apify dataset or over the API.

**Q: Is this legal?**
A: We read only what posters chose to publish. See the note below on personal data.

***

### 🐛 Troubleshooting

**The run returned no listings**

- Check the address opens in a browser and shows ads. An empty search here is an empty search there.
- A bedroom filter on the for-sale categories narrows things to almost nothing — sale ads rarely carry a bedroom count.
- A price band drops every "Please Contact" ad, which is roughly 7% of the board.

**I pasted an address and got "no usable search addresses"**

- A Kijiji search address ends in the category and location code, like `.../c37l1700273`. An ad address (`/v-...`) belongs in 📄 Ad addresses or IDs instead.

**Fewer rows than I asked for**

- On the FREE tier every run stops at 25 rows.
- Kijiji stops paging a single search at about 5,000 results, whatever tool is asking.

**A specific ad came back as an error**

- It was taken down between the search and the read. Re-run the search to pick up what is live now.

**The run is slower than expected**

- 🔬 depth opens every ad on its own page, so a 1,000-ad sweep becomes 1,001 page reads. Turn it off unless you need the full text or the poster.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

Kijiji is a trademark of its respective owner. This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Kijiji.

***

### 🤝 Support

**Join our active support community**

- For issues or questions, open an issue in the actor's repository
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

🔍 **Listing search** sweeps a Kijiji real-estate search — pasted URL or built from the fields below — and returns 46 ads per page with price, beds, baths, size, utilities, amenities, coordinates and who posted it. 📄 **Listing detail** takes an ad address or id and returns the untruncated description, the full photo set, the view count, the poster's profile and their contact line.

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

🌐 **PASTE A SEARCH FROM KIJIJI.** Set up the search on kijiji.ca with whatever filters you want, then copy the address bar and drop it here.

🧠 **Every filter in the address is honoured** — bedrooms, price band, pet rules, utilities, unit type, accessibility — because the page is fetched exactly as pasted and Kijiji resolves it.

🇫🇷 French addresses work too: `/b-immobilier/…` returns the same listings as `/b-real-estate/…`.

📥 **BULK:** one address per line, or upload a .txt file.

## `keywords` (type: `string`):

🔑 **WORDS THAT MUST APPEAR IN THE AD.** Searches the ad title and body — 'basement', 'pet friendly', 'utilities included', 'walkout'. 💡 **TIP:** leave it empty and pick a category to sweep that whole section newest-first, which is the shape you want for a daily monitor. 🧩 Keyword, category and location combine.

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

🗂️ **WHICH SECTION TO SWEEP.** For rent, as Kijiji counted it on 2026-09-06: long-term rentals 48,347 · rooms & roommates 11,101 · commercial 11,357 · short-term 2,163 · storage & parking 712.

For sale: houses 96,549 · condos 33,337 · land 29,040 · commercial 10,239. All real estate together is 242,932.

💡 Rooms & roommates and long-term rentals are where private landlords post; the for-sale branches are mostly agents.

## `location` (type: `string`):

📍 **WHERE TO LOOK.** Every value here was read off Kijiji's own location picker, so none of them 404. 🔎 **Need a smaller area** — a single suburb, a postal district, a neighbourhood? Open it on kijiji.ca and paste that address into 🌐 Kijiji search URLs instead; this list stops at province and metro.

## `listedBy` (type: `string`):

👤 **THE FILTER THAT MAKES KIJIJI WORTH READING.** About 22,000 of the 48,000 long-term rentals are posted by the owner, not a property manager.

🏡 **Owner** keeps ads the poster flagged as their own. 🏢 **Professional** keeps managers, brokerages and agents.

⚠️ Kijiji offers this in the rental categories, houses, condos and land — not in all real estate, rooms or commercial for sale. Picking it there is refused, never silently ignored.

ℹ️ Every row carries `listedBy` anyway.

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

🛏️ **EXACT BEDROOM COUNT.** Kijiji treats a den as a half, so '1 + den' is its own bucket rather than a rounded 1 or 2. ⚠️ Only rental ads carry a bedroom count — for-sale and land ads mostly leave it blank, so this narrows those sections to almost nothing.

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

💵 **FLOOR PRICE IN CANADIAN DOLLARS.** Monthly rent in the rental sections, asking price in the for-sale ones. 0 means no floor. ⚠️ Ads priced 'Please Contact' carry no number at all and drop out as soon as you set either bound — about 7% of the board.

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

💰 **CEILING PRICE IN CANADIAN DOLLARS.** 0 means no ceiling. Set it together with the floor to take a band — 1,500 to 2,500 a month, say.

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

↕️ **WHICH ADS COME BACK FIRST.** This matters whenever 🔢 Maximum results is smaller than the section, because you keep the front of the order and drop the tail. 🆕 Newest first is what a change monitor wants. ⬆️ Cheapest first is what a deal sweep wants.

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

🔢 **HOW MANY ADS PER SEARCH, AND THEREFORE WHAT THE RUN COSTS.** It is a cap per search address, so three pasted addresses at 100 return up to 300 ads. Kijiji serves 46 ads per page, so the actor reads ceil(results ÷ 46) pages of each.

💡 100 is a sensible look; 1,000 is a working dataset; 5,000 is the deepest one search reaches before Kijiji stops paging — split the query by city or price band to go past that.

## `enrichWithDetails` (type: `boolean`):

🔬 **FETCHES EVERY AD'S OWN PAGE ON TOP OF THE SEARCH.** Search rows carry Kijiji's own snippet, cut at about 200 characters; this adds the untruncated description and the full-resolution photo set. It also adds the view counter, the expiry date, the virtual-tour link and the poster's profile.

💸 **It bills one 📄 Listing Detail charge per ad** on top of the search charge, and costs one extra page fetch. Turn it on when you need the text or the poster, not to browse.

## `listingUrls` (type: `array`):

📄 **READ NAMED ADS DIRECTLY.** Paste full ad addresses (`https://www.kijiji.ca/v-apartments-condos/…/1742889268`) or bare numeric ids (`1742889268`) — both work. 🧾 Each one returns the same full record 🔬 enrichment produces, and bills one 📄 Listing Detail charge. ♻️ **Use it to re-check ads you already have:** an ad that has been taken down comes back with its status instead of an error.

## Actor input object example

```json
{
  "operation": "search",
  "searchUrls": [
    "https://www.kijiji.ca/b-apartments-condos/city-of-toronto/c37l1700273?for-rent-by=ownr"
  ],
  "keywords": "basement",
  "category": "37",
  "location": "0",
  "listedBy": "any",
  "bedrooms": "any",
  "minPrice": 0,
  "maxPrice": 0,
  "sortBy": "dateDesc",
  "maxItems": 100,
  "enrichWithDetails": false,
  "listingUrls": [
    "https://www.kijiji.ca/v-apartments-condos/gatineau/semi-detached-home-for-rent-maison-jumelee-a-louer/1742889268"
  ]
}
```

# Actor output Schema

## `kijijiListings` (type: `string`):

Every listing this run returned.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "searchUrls": [],
    "keywords": "",
    "category": "37",
    "location": "0",
    "listedBy": "any",
    "bedrooms": "any",
    "minPrice": 0,
    "maxPrice": 0,
    "sortBy": "dateDesc",
    "maxItems": 100,
    "enrichWithDetails": false,
    "listingUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/kijiji-property-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 = {
    "operation": "search",
    "searchUrls": [],
    "keywords": "",
    "category": "37",
    "location": "0",
    "listedBy": "any",
    "bedrooms": "any",
    "minPrice": 0,
    "maxPrice": 0,
    "sortBy": "dateDesc",
    "maxItems": 100,
    "enrichWithDetails": False,
    "listingUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/kijiji-property-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 '{
  "operation": "search",
  "searchUrls": [],
  "keywords": "",
  "category": "37",
  "location": "0",
  "listedBy": "any",
  "bedrooms": "any",
  "minPrice": 0,
  "maxPrice": 0,
  "sortBy": "dateDesc",
  "maxItems": 100,
  "enrichWithDetails": false,
  "listingUrls": []
}' |
apify call sian.agency/kijiji-property-scraper --silent --output-dataset

```

## MCP server setup

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