# Centris Scraper (`memo23/centris-scraper`) Actor

Scrape Quebec real estate from Centris.ca: houses, condos, plexes, lots, commercial and rentals. Price, address, beds, baths, GPS, photos, Centris number. Full details add description, year built, area, taxes, assessment, brokers with phones and all photos. Search by URL or city.

- **URL**: https://apify.com/memo23/centris-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Centris Scraper: Quebec Real Estate Listings from Centris.ca

Turn any Centris.ca search or listing URL into clean rows of Quebec real estate data.
Paste a search URL, a listing URL, or just type a city, and get price, address, bedrooms, bathrooms, GPS coordinates and photos for houses, condos, plexes, lots, commercial property and rentals. Turn on full details to add the description, year built, living and lot area, municipal assessment, yearly taxes, condo fees, Walk Score, every listing broker with phone numbers, and the complete photo gallery with captions.

### Why Use This Scraper?

- **Start from a URL or a city.** Paste Centris search or listing URLs, or type a city (accents and spaces are fine) and pick sale or rent and a property type.
- **All of Quebec.** Montréal and its boroughs, Laval, Quebec City, Gatineau, Sherbrooke, Trois-Rivières, Longueuil, Lévis and any other city Centris has a search page for.
- **Fast card mode.** One request returns 20 listings with price, address, beds, baths, GPS and the main photo.
- **Full details when you need them.** Description, rooms, year built, areas, every characteristic on the page, municipal assessment, taxes, condo fees and Walk Score.
- **Broker contacts.** Every listing broker with title, agency, phone numbers in `+1 XXX-XXX-XXXX` format and Centris profile link.
- **Every photo.** The full gallery with captions at 1260×1024, the largest size Centris serves.
- **English and French pages.** Both `/en/` and `/fr/` URLs work.
- **No silent empty runs.** A misspelled city returns one row that says what went wrong.

### Overview

The Centris Scraper is built for real estate investors, brokers, proptech teams and market analysts who need structured listing data from Centris.ca, the listing site used by Quebec's real estate brokers.

The output is always **one row per listing**. Whether you start from a city, a search URL or a single listing URL, the dataset is a stream of listing rows. Brokers and photos are nested inside each listing row; they are not separate rows.

The actor has two depths:

- **Card-only (default).** The fields on the search results card. One request covers 20 listings.
- **Full details (`fetchFullDetails: true`).** Also opens each listing's page and photo list for the description, characteristics, finances, brokers and every photo. Two extra requests per listing.

A listing URL given as input always returns the full row, whatever `fetchFullDetails` is set to.

### Supported Inputs

#### URL types

| URL type | Pattern | Example |
|---|---|---|
| Search results (English) | `/en/<type>~<for-sale or for-rent>~<city>` | `https://www.centris.ca/en/condos~for-sale~montreal` |
| Search results (French) | `/fr/<type>~<a-vendre or a-louer>~<city>` | `https://www.centris.ca/fr/propriete~a-vendre~montreal` |
| Listing page (English) | `/en/<type>~<transaction>~<city>/<Centris number>` | `https://www.centris.ca/en/condos~for-sale~montreal-ville-marie/20267781` |
| Listing page (French) | `/fr/<type>~<transaction>~<city>/<Centris number>` | `https://www.centris.ca/fr/condo~a-vendre~montreal-ville-marie/20267781` |

#### Copy-pasteable startUrls

```json
{
  "startUrls": [
    { "url": "https://www.centris.ca/en/condos~for-sale~montreal" },
    { "url": "https://www.centris.ca/en/cottages~for-sale~sherbrooke" },
    { "url": "https://www.centris.ca/en/condos~for-sale~montreal-ville-marie/20267781" }
  ],
  "maxItems": 200
}
```

You can mix search URLs and listing URLs in one run. The same listing found twice (for example, the English and French URL of one property, or a condo that shows up in two searches) is returned once, keyed by its Centris number.

#### City search mode

Leave `startUrls` empty and the actor builds the search from three fields:

```json
{
  "city": "Trois-Rivières",
  "transaction": "for-sale",
  "propertyType": "houses",
  "maxItems": 100
}
```

- **City** takes plain names with accents and spaces: `montreal`, `laval`, `gatineau`, `sherbrooke`, `Trois-Rivières`, `longueuil`, `levis`.
- **Boroughs** work too: `Montréal (Ville-Marie)` searches the Ville-Marie borough only.
- **Quebec City**: type `Quebec City` or `quebec`. Both map to Centris's `quebec` page.
- The Console prefills `city` with `montreal`. That value is ignored as soon as `startUrls` has a URL in it.

#### Property types

| `propertyType` | For sale | For rent |
|---|---|---|
| `properties` (all residential) | yes | yes |
| `houses` | yes | yes |
| `condos` | yes | yes (condos / apartments) |
| `plexes`, `duplexes`, `triplexes` | yes | no, sale only |
| `lofts-studios`, `intergenerational-homes`, `cottages`, `mobile-homes` | yes | yes |
| `lots`, `farms` | yes | yes |
| `commercial-properties`, `offices`, `businesses` | yes | yes |

Asking for plexes, duplexes or triplexes with `for-rent` stops the run at once with a message explaining the fix.

#### Unsupported inputs

- URLs outside `centris.ca`. They are skipped with a warning; if none of the start URLs is valid, the run fails with a clear message.
- Broker profile pages and agency pages as start URLs.
- Filters from the Centris filter panel (price range, number of bedrooms and so on). Narrow the search by property type, transaction and city or borough, then filter the dataset on `price`, `bedrooms` and the other fields.
- Saved searches, favourites and anything else behind a Centris login.
- Sold prices and listing history. The actor returns the listings Centris currently shows.

### Use Cases

| Audience | Use case |
|---|---|
| **Real estate investors** | Screen Montréal plexes by price, unit mix and potential gross revenue, then compare taxes and assessments. |
| **Brokers and agencies** | See who holds the listings in a territory: brokers, agencies and phone numbers. |
| **Proptech and data teams** | Feed Quebec listings with GPS, photos and descriptions into a search product, map or valuation model. |
| **Market analysts and researchers** | Compare asking prices, municipal assessments and yearly taxes by city, borough or property type. |
| **Rental and relocation services** | Collect monthly rents for condos and houses for rent across Quebec. |

### How It Works

![How the Centris Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-centris.png)

1. **Input.** Give Centris search or listing URLs, or a city with sale or rent and a property type.
2. **Page through the results.** Each search is read 20 listings at a time, in a fixed order, until `maxItems` or `maxPages` is reached.
3. **Read the cards.** Price, address, city, region, bedrooms, bathrooms, coordinates, main photo and photo count come straight from the results page.
4. **Full details (optional).** With `fetchFullDetails`, each listing page and its photo list are fetched for the description, characteristics, finances, brokers and every photo.
5. **Output.** Listings are deduplicated by Centris number and written as one row each, ready to export as JSON, CSV or Excel.

### Input Configuration

#### Input fields

| Field | Type | Default | Notes |
|---|---|---|---|
| `startUrls` | array of `{ "url": string }` | none | Centris search or listing URLs, English or French. When this has URLs, the city search is not used. |
| `city` | string | none (Console prefills `montreal`) | Quebec city or borough to search when `startUrls` is empty. Accents and spaces are fine. |
| `transaction` | string: `for-sale`, `for-rent` | `for-sale` | Used with `city`. |
| `propertyType` | string (15 values, see table above) | `properties` | Used with `city`. `plexes`, `duplexes` and `triplexes` are sale only. |
| `maxItems` | integer | `100` | Maximum listings to return across all searches. |
| `maxPages` | integer | `0` | Stop each search after this many result pages (20 listings each). `0` means no page limit. |
| `fetchFullDetails` | boolean | `false` | Open each listing's page for the description, characteristics, finances, brokers and all photos. Adds two requests per listing. |
| `maxConcurrency` | integer (1 to 50) | `10` | How many Centris requests run at once. |
| `proxy` | object | Apify datacenter proxy | Switch to residential only if runs fail with HTTP 403. |

#### Common scenarios

**1. Fast card-only pull for a city**

```json
{
  "city": "montreal",
  "maxItems": 250
}
```

**2. Full details for condos from a search URL**

```json
{
  "startUrls": [{ "url": "https://www.centris.ca/en/condos~for-sale~montreal" }],
  "fetchFullDetails": true,
  "maxItems": 50
}
```

**3. Condo rentals in Quebec City**

```json
{
  "city": "Quebec City",
  "transaction": "for-rent",
  "propertyType": "condos",
  "maxItems": 100
}
```

**4. Specific listings (always returned with full details)**

```json
{
  "startUrls": [
    { "url": "https://www.centris.ca/en/condos~for-sale~montreal-ville-marie/20267781" },
    { "url": "https://www.centris.ca/en/duplexes~for-sale~montreal-saint-laurent/10046657" }
  ]
}
```

### Output Overview

Each dataset item is one Centris listing. Every row has the card fields; full-details rows add the rest.

- **Identity**: Centris number, URL, sale or rent, category ("Condo for sale").
- **Price**: number, text as shown (keeps "+ GST/QST" and "/month"), currency.
- **Location**: address, city (with borough for Montréal), region, coordinates.
- **Layout**: bedrooms, bathrooms; rooms, year built, living and lot area with full details.
- **Media**: main photo, photo count, virtual tour; every captioned photo with full details.
- **Finances (full details)**: municipal assessment with its year, yearly taxes, condo fees.
- **Brokers (full details)**: every listing broker with title, agency, phones and profile URL; the first one also as flat `brokerName`, `brokerPhone`, `agency` columns.

Fields the page does not show come back as `null`; the rental sample below has no assessment or taxes, for example.

Keys inside `characteristics`, `municipalAssessment`, `yearlyTaxes` and `yearlyFees` are Centris's own labels, so they are in French when you use French URLs. The `description` is in whatever language the broker wrote it; many are in French even on English pages.

### Output Samples

#### Card-only row (city search, default settings)

```json
{
  "listingId": "17307495",
  "url": "https://www.centris.ca/en/triplexes~for-sale~montreal-rosemont-la-petite-patrie/17307495",
  "transaction": "sale",
  "category": "Triplex for sale",
  "price": 1149000,
  "priceText": "$1,149,000",
  "currency": "CAD",
  "address": "6738 - 6742, 6e Avenue",
  "city": "Montréal (Rosemont/La Petite-Patrie)",
  "region": "Montréal (Island)",
  "bedrooms": 3,
  "bathrooms": 1,
  "latitude": 45.553481,
  "longitude": -73.593409,
  "photoUrl": "https://mspublic.centris.ca/media.ashx?id=ADDD250DAD14633DDDDDDDDDDC&t=pi&w=1260&h=1024&sm=c",
  "photoCount": 22,
  "virtualTourUrl": null,
  "scrapedAt": "2026-09-28T16:07:21.242Z"
}
```

#### Full-details row, plex for sale (`fetchFullDetails: true`, photos trimmed to 3 of 25)

```json
{
  "listingId": "10708877",
  "url": "https://www.centris.ca/en/5plex~for-sale~montreal-villeray-saint-michel-parc-extension/10708877",
  "transaction": "sale",
  "category": "Quintuplex for sale",
  "price": 1449000,
  "priceText": "$1,449,000",
  "currency": "CAD",
  "address": "7568 - 7576, Rue Saint-Dominique",
  "city": "Montréal (Villeray/Saint-Michel/Parc-Extension)",
  "region": "Montréal (Island)",
  "bedrooms": 3,
  "bathrooms": 2,
  "latitude": 45.537021,
  "longitude": -73.622858,
  "photoUrl": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA280865DDDDDDDDDDA&t=pi&w=1260&h=1024&sm=c",
  "photoCount": 25,
  "virtualTourUrl": null,
  "description": "SUPERB 5PLEX -- NESTLED IN THE HEART OF VILLERAY -- IN HIGHLY SOUGHT-AFTER AREA (family-friendly St-Dominique street) -- Ideal for an owner-occupant, this magnificent 5plex offers a generous 28-foot facade and has been well maintained over the years, including the installation of a new furnace in 2026, 3 fiberglass front balconies, etc. (see addendum). Enjoy a prime location just 350 meters from De Castelnau metro station and in close proximity to all amenities: Little Italy, Jean-Talon Market, Jarry Park, daycares, schools, restaurants, cafes, pharmacies, and quick access to Highway 40. A rare find in the neighborhood -- great opportunity!",
  "rooms": 6,
  "yearBuilt": 1929,
  "livingArea": "3,496 sqft",
  "lotArea": "2,100 sqft",
  "characteristics": {
    "Use of property": "Residential",
    "Building style": "Attached",
    "Year built": "1929",
    "Living area": "3,496 sqft",
    "Lot area": "2,100 sqft",
    "Number of units": "Residential (5)",
    "Residential units": "2 x 3 ½, 2 x 4 ½, 1 x 6 ½",
    "Main unit": "6 rooms, 3 bedrooms, 2 bathrooms",
    "Potential gross revenue": "$54,000",
    "Additional features": "Basement 6 feet or +",
    "Move-in date": "180 days after acceptance of promise to purchase or rent"
  },
  "municipalAssessment": { "year": 2026, "Lot": 390200, "Building": 900500, "Total": 1290700 },
  "yearlyTaxes": { "Municipal (2026)": 8296, "School (2026)": 974, "Total": 9270 },
  "yearlyFees": null,
  "walkScore": 97,
  "brokers": [
    {
      "name": "Steve Velosa",
      "title": "Residential and Commercial Real Estate Broker",
      "agency": "RE/MAX DU CARTIER INC.",
      "phones": ["+1 514-755-5505"],
      "profileUrl": "https://www.centris.ca/en/real-estate-broker~steve-velosa~re-max-du-cartier-inc.-villeray/d4094"
    }
  ],
  "brokerName": "Steve Velosa",
  "brokerPhone": "+1 514-755-5505",
  "agency": "RE/MAX DU CARTIER INC.",
  "photos": [
    { "url": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA280865DDDDDDDDDDA&t=pi&w=1260&h=1024&sm=c", "caption": "Frontage" },
    { "url": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA28088ADDDDDDDDDDA&t=pi&w=1260&h=1024&sm=c", "caption": "Kitchen" },
    { "url": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA280881DDDDDDDDDD1&t=pi&w=1260&h=1024&sm=c", "caption": "Kitchen" }
  ],
  "scrapedAt": "2026-09-28T16:07:21.696Z"
}
```

#### Full-details row, condo for rent (photos trimmed to 2 of 40)

```json
{
  "listingId": "12783346",
  "url": "https://www.centris.ca/en/condos-apartments~for-rent~montreal-cote-des-neiges-notre-dame-de-grace/12783346",
  "transaction": "rent",
  "category": "Condo / Apartment for rent",
  "price": 3650,
  "priceText": "$3,650 /month",
  "currency": "CAD",
  "address": "5592, Rue Snowdon",
  "city": "Montréal (Côte-des-Neiges/Notre-Dame-de-Grâce)",
  "region": "Montréal (Island)",
  "bedrooms": 3,
  "bathrooms": 2,
  "latitude": 45.478964,
  "longitude": -73.629352,
  "photoUrl": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA15B290DDDDDDDDDD0&t=pi&w=1260&h=1024&sm=c",
  "photoCount": 40,
  "virtualTourUrl": null,
  "description": "Discount of 1/2 of 1st month rent!!! Spacious Family 2-Floor Apartment for Rent in a Prime Location! Lower duplex with 3 bedrooms, 2 bathrooms, a finished basement, double garage, driveway, deck and backyard located in a sought-after neighborhood in CDN/NDG. Enjoy the outdoor space with a private terrace & backyard. 2 steps away from Solomon Schechter, grocery stores IGA and Métro, shops and restaurants, pharmacies, banks, UdM, many schools and hospitals. Walking distance to many buses and located between 2 metro stations Snowdon and Villa Maria and close by Décarie and highway 15. Available as of August 1, 2026.",
  "rooms": 7,
  "yearBuilt": null,
  "livingArea": null,
  "lotArea": null,
  "characteristics": { "Move-in date": "According to leases" },
  "municipalAssessment": null,
  "yearlyTaxes": null,
  "yearlyFees": null,
  "walkScore": 95,
  "brokers": [
    {
      "name": "Myong Hee Kim",
      "title": "Residential and Commercial Real Estate Broker",
      "agency": "LES IMMEUBLES CHARISMA INC.",
      "phones": ["+1 514-688-8503"],
      "profileUrl": "https://www.centris.ca/en/real-estate-broker~myong-hee-kim~les-immeubles-charisma-inc.-siege-social/e0878"
    }
  ],
  "brokerName": "Myong Hee Kim",
  "brokerPhone": "+1 514-688-8503",
  "agency": "LES IMMEUBLES CHARISMA INC.",
  "photos": [
    { "url": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA15B290DDDDDDDDDD0&t=pi&w=1260&h=1024&sm=c", "caption": "Hall" },
    { "url": "https://mspublic.centris.ca/media.ashx?id=ADDD250DA15B29ADDDDDDDDDDA&t=pi&w=1260&h=1024&sm=c", "caption": "Hall" }
  ],
  "scrapedAt": "2026-09-28T16:07:21.776Z"
}
```

#### Run that found nothing (misspelled city)

```json
{
  "noResults": true,
  "reason": "not_found",
  "message": "Centris has no page at https://www.centris.ca/en/properties~for-sale~quebecc-cityy. Check the city spelling (e.g. montreal, laval, quebec, trois-rivieres) or open the URL in a browser.",
  "scrapedAt": "2026-09-28T16:02:42.128Z"
}
```

### Key Output Fields

#### Listing identity

- `listingId` (the Centris number), `url`, `transaction` (`sale` or `rent`), `category`, `scrapedAt`

#### Price

- `price` (number), `priceText` (as shown, e.g. `$459,900 + GST/QST` or `$3,650 /month`), `currency` (`CAD`)

#### Location

- `address`, `city` (with borough for Montréal), `region`, `latitude`, `longitude`

#### Property

- `bedrooms`, `bathrooms` (every row)
- `rooms`, `yearBuilt`, `livingArea`, `lotArea`, `walkScore` (full details)
- `characteristics`: every label and value from the listing page, such as building style, number of units, move-in date or potential gross revenue (full details)

#### Finances (full details)

- `municipalAssessment` (with `year`, lot, building and total values), `yearlyTaxes` (municipal, school, total), `yearlyFees` (condo fees)

#### Brokers (full details)

- `brokers[]`: `name`, `title`, `agency`, `phones[]`, `profileUrl`
- `brokerName`, `brokerPhone`, `agency`: the first broker, as flat columns

#### Media

- `photoUrl`, `photoCount`, `virtualTourUrl` (every row)
- `photos[]`: `url` and `caption` for every photo, 1260×1024 (full details)

#### Empty-run row

- `noResults`, `reason` (`not_found` or `legit_empty`), `message`

### FAQ

#### Which Centris URLs work?

Search results pages and single listing pages on `centris.ca`, in English (`/en/`) or French (`/fr/`). A search URL follows the pattern `/<type>~<transaction>~<city>`, for example `https://www.centris.ca/en/houses~for-sale~laval`. Broker and agency pages are not supported as start URLs.

#### How much does it cost?

You pay per event, with no subscription:

| Event | Price | When |
|---|---|---|
| Run start | $0.005 | Once per run |
| Listing | $0.0015 | Every row in the dataset ($1.50 per 1,000) |
| Full listing details | $0.0025 | Every listing whose own page was read: with `fetchFullDetails` on, or for listing URLs given as input |

So 1,000 card-only listings cost about $1.50, and 1,000 listings with full details about $4. Set a spending limit on the run and the actor stops opening listing pages once the limit is reached.

#### Card-only or full details: which should I use?

Card-only is the fast option: one request per 20 listings, with price, address, beds, baths, GPS and the main photo. Use `fetchFullDetails` when you need the description, finances, brokers or the full gallery; it adds two requests per listing. If a listing page fails to load, you still get that listing's card data rather than losing the row.

#### How do I get more than 5,000 listings for a city?

Centris shows at most 5,000 listings for a single search (250 pages of 20). Split large searches into several start URLs, one per property type (condos, houses, plexes and so on) or one per borough. Listings that appear in more than one search are returned once.

#### Why are some fields in French?

The `description` is in the language the broker wrote it, and many Quebec brokers write in French. The keys inside `characteristics`, `municipalAssessment`, `yearlyTaxes` and `yearlyFees` are Centris's own labels, so they follow the language of the URL. Use `/en/` URLs for English labels.

#### Why did my run fail when I asked for plexes for rent?

Plexes, duplexes and triplexes are only listed for sale on Centris, so there is no rental search to read. Switch `transaction` to `for-sale`, or use `properties` or `houses` for rentals.

#### My dataset has a row with `noResults: true`. What does it mean?

The run finished but found no listings, and the row says why. `not_found` means Centris has no page for that city or URL (usually a spelling issue); `legit_empty` means the search is valid but has no listings right now. If Centris blocks the requests or the page layout changes, the run fails with an error instead of writing this row.

#### Does it return broker email addresses?

No. The actor returns each listing broker's name, title, agency, phone numbers and Centris profile link.

#### Do I need a residential proxy?

Usually not. The default Apify datacenter proxy works for Centris search and listing pages. Switch to residential only if your runs start failing with HTTP 403.

#### Can I scrape sold listings or content behind a login?

No. The actor reads the public Centris.ca pages and returns the listings Centris currently shows. Saved searches, favourites and account features are out of scope.

#### Which export formats are available?

Any format the Apify dataset supports: JSON, CSV, Excel, XML, HTML and more.

### Support

- For bugs or feature requests, open an issue on the actor's [Issues tab](https://apify.com/memo23/centris-scraper/issues).
- For anything else, contact the author:
  - Website: <https://muhamed-didovic.github.io/>
  - Email: <muhamed.didovic@gmail.com>

### Additional Services

Need a scheduled Quebec listings feed, delivery to a database or Google Sheets, a custom field set, or a scraper for another real estate portal? Custom actors and data pipelines are available. Get in touch using the contacts above.

### Explore More Scrapers

- [**Realtor.ca Scraper**](https://apify.com/memo23/realtor-canada-search-cheerio-ppe): Canadian listings and real estate agent contacts
- [**Zillow Scraper**](https://apify.com/memo23/zillow-scraper-ppe): US homes for sale, for rent and sold
- [**Redfin Scraper**](https://apify.com/memo23/apify-redfin-cheerio-ppe): US listings plus an agent database with email and phone
- [**Rightmove Scraper**](https://apify.com/memo23/rightmove-scraper): UK property to buy and rent
- [**Idealista Scraper**](https://apify.com/memo23/idealista-scraper): Spain, Italy and Portugal property listings

Full list at [apify.com/memo23](https://apify.com/memo23).

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/centris-scraper`).

**Purpose:** Returns Quebec real estate listings from Centris.ca (sale and rent, all property types) as one row per listing, with optional full details: finances, brokers with phones, and every photo.

**Minimal input:**

```json
{ "city": "montreal", "maxItems": 20 }
```

For specific searches or listings, pass `"startUrls": [{ "url": "https://www.centris.ca/en/condos~for-sale~montreal" }]` instead. Optional: `transaction` (`for-sale`, `for-rent`), `propertyType`, `maxPages`, `fetchFullDetails`.

**Output:** one dataset row per listing: listingId, url, transaction, category, price, priceText, currency, address, city, region, bedrooms, bathrooms, latitude, longitude, photoUrl, photoCount, virtualTourUrl, scrapedAt. With `fetchFullDetails: true` or a listing URL as input, also: description, rooms, yearBuilt, livingArea, lotArea, characteristics {label: value}, municipalAssessment {year, ...}, yearlyTaxes, yearlyFees, walkScore, brokers \[{name, title, agency, phones\[], profileUrl}], brokerName, brokerPhone, agency, photos \[{url, caption}].

**Behaviors an agent should know:**

- `startUrls` wins: when it has URLs, `city`, `transaction` and `propertyType` are ignored.
- `maxItems` defaults to 100. One Centris search tops out at 5,000 listings; split by `propertyType` or borough for more.
- Card-only mode costs one request per 20 listings; `fetchFullDetails` adds two requests per listing.
- Results are deduplicated by Centris number across all inputs.
- `plexes`, `duplexes`, `triplexes` with `for-rent` fail the run immediately (sale only on Centris).
- A run with no listings writes one row `{noResults: true, reason, message}`; `reason` is `not_found` (bad city or URL) or `legit_empty`.
- Nested object keys are Centris labels (French on `/fr/` URLs); `description` is in the broker's language.
- No broker emails.
- Billing (pay per event): $0.005 per run start, $0.0015 per listing row, plus $0.0025 per listing whose own page was read (`fetchFullDetails: true`, or a listing URL as input). The empty-run explanation row counts as one listing row.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Centris Corporation inc. (the operator of Centris.ca), the Quebec Professional Association of Real Estate Brokers (QPAREB / APCIQ), or any of their affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available Centris.ca listing pages: no authenticated endpoints, no account features, and no content behind the Centris login. Rows can include broker names and business phone numbers as published on Centris.ca. Users are responsible for making sure their use complies with Centris.ca's Terms of Use, applicable privacy and data-protection law (Quebec's Law 25, PIPEDA, GDPR, CCPA and similar), anti-spam rules such as CASL for any outreach, and any contractual obligations of their own organization.

***

### SEO Keywords

Centris scraper, Centris.ca scraper, scrape Centris, Centris API, Apify Centris, Quebec real estate scraper, Quebec property listings, Montreal real estate data, Montreal condo prices, Montreal plex for sale, Laval houses for sale, Quebec City rentals, Canadian housing market, property listings export, broker phone numbers, listing broker contacts, municipal assessment values, yearly property taxes, listing photos scraper, proptech data feed, real estate investment research

# Actor input Schema

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

Centris.ca search URLs (e.g. https://www.centris.ca/en/properties~for-sale~montreal) or listing URLs (e.g. https://www.centris.ca/en/condos~for-sale~montreal-ville-marie/20267781). English and French URLs both work. When this list has URLs, the city search below is not used.

## `city` (type: `string`):

Quebec city or borough to search when Start URLs is empty, e.g. montreal, laval, quebec (Quebec City), gatineau, sherbrooke, trois-rivieres, longueuil, levis, montreal-ville-marie. Accents and spaces are fine.

## `transaction` (type: `string`):

For sale or for rent. Used with City; ignored when Start URLs has URLs.

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

Property type to search. Used with City; ignored when Start URLs has URLs. Plexes, duplexes and triplexes exist only for sale on Centris.

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

Maximum number of listings to return across all searches. Default 100.

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

Stop each search after this many result pages (20 listings per page). 0 = no page limit, only Max results applies. Centris shows at most 5,000 listings (250 pages) for one search; split large cities by property type or borough to go further.

## `fetchFullDetails` (type: `boolean`):

Open each listing's page for the full description, rooms, year built, living and lot area, all characteristics, municipal assessment, yearly taxes and fees, Walk Score, every listing broker with phone numbers and agency, and all photos with captions. Adds two requests per listing.

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

How many Centris requests run at once (1-50).

## `proxy` (type: `object`):

Centris answers Apify's datacenter proxies, which is the default. Switch to RESIDENTIAL only if runs start failing with HTTP 403.

## Actor input object example

```json
{
  "city": "montreal",
  "transaction": "for-sale",
  "propertyType": "properties",
  "maxItems": 100,
  "maxPages": 0,
  "fetchFullDetails": false,
  "maxConcurrency": 10,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "city": "montreal",
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/centris-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 = {
    "city": "montreal",
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/centris-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 '{
  "city": "montreal",
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call memo23/centris-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/centris-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/6O0Bd0hPU9btcTCMF/builds/1kcXsDh5SShR7LGq3/openapi.json
