Realtor.ca - Property Listings, Prices, Agents & Open Houses avatar

Realtor.ca - Property Listings, Prices, Agents & Open Houses

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Realtor.ca - Property Listings, Prices, Agents & Open Houses

Realtor.ca - Property Listings, Prices, Agents & Open Houses

From $1/1K. Scrape Realtor.ca property listings with prices, descriptions, images, agent and brokerage details, coordinates, open house times, building features, and more.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(2)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

4

Bookmarked

52

Total users

3

Monthly active users

7 days ago

Last modified

Share

Realtor.ca Scraper: Canadian Property Listings, Prices & Agent Details

Realtor.ca Scraper turns Realtor.ca, Canada's national property listing site, into a clean property data feed. Search any Canadian city and province, or paste a search URL you already refined on the site, and get full listing details: price, full address with coordinates, bedrooms and bathrooms, building features, every listing photo, and the listing agent's contact and brokerage details. Covers homes for sale, for rent, and recently sold, across residential, commercial, condo, multi-family, vacant land and more, then export to JSON, CSV or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Two ways to search. Pick a city and province with filters, or paste a Realtor.ca search URL already refined in a browser.
  • Every property category. Residential, commercial, condo, multi-family, vacant land, recreational, agriculture and parking listings, across all 13 Canadian provinces and territories.
  • Full listing depth. Price, full address with coordinates, bedrooms, bathrooms, parking, land and building size, building features, and every listing photo.
  • Agent and brokerage details on every listing. Name, phone, position, profile link, brokerage name, logo, website and phone.
  • Built for schedules. Incremental mode returns only new and changed listings on recurring runs, and a genuine connection failure fails loudly instead of returning an empty dataset.
  • Two independent ways to avoid rescraping. Continue one interrupted run from its run or dataset ID, or track a recurring search with Incremental mode.

Use Cases

  • Real estate agents and investors: track new listings, price changes and sold comparables in target neighborhoods.
  • Property portals and apps: feed listing search, pricing and photos into your own site or app.
  • Market research and analytics: build historical pricing datasets by city, province and property type.
  • Relocation and rental services: monitor rental listings and open houses across cities.
  • Lead generation: collect agent and brokerage contact details tied to active listings.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
propertyId"12345678"
mlsNumber"C1234567"
urlFull listing URL on Realtor.ca
listingType"buy" (also "rent", "sold")
propertyType"condo" (also "apartment", "house", "townhouse", "duplex", "triplex", "fourplex", "multi-family", "modular", "vacant-land", "parking", "commercial", "farm", "other")
buildingType"Apartment" (raw building type as published)
ownershipType"Condominium/Strata"
Listing description textNot included. realtor.ca returns the remarks field empty in search results and only serves it on the listing-detail endpoint, which refuses requests (HTTP 403).
dateListed / timeOnRealtor"2026-03-19T10:00:00.000Z" / "2 hours ago"
communityName, statusIdExtra listing attributes, present only when realtor.ca publishes them for that listing (omitted otherwise, never estimated)
addressfull, street, city, province, postalCode
coordinateslatitude, longitude
pricedisplay (formatted string), value (numeric CAD)
featuresbedrooms, bathrooms, parkingSpaces, parkingType, landSize, buildingSize, stories
propertyFeaturesBuilding amenities and construction details, e.g. ["Central air conditioning", "Style: Bungalow"]
tagsListing tags shown on the site, e.g. ["Open House"]
mediaimageCount, images (high resolution photo URLs)
agentsOne entry per listing agent: name, phone, position, profile link, brokerage name, brokerage ID (organizationId), logo, website, phone
openHouseUpcoming open house entries: startTime, endTime, comments
scrapedAt"2026-03-19T12:00:00.000Z"
changeType / changedFields / firstSeenAt / lastSeenAtOnly present when Incremental mode is on: "NEW", "UPDATED", "UNCHANGED", "REAPPEARED" or "EXPIRED", the fields that changed, and when the listing was first and last seen

How to Use

  1. Pick a mode: Location (city and province, plus filters) or URL (paste one or more Realtor.ca search URLs).
  2. In Location mode, add one or more cities and set the filters you need: listing type, property category, building type, price, bedrooms, bathrooms, open house. In URL mode, paste the URL(s) instead; the filter fields above are ignored because the URL already carries them, but set Listing Type to match the URL since it labels each row's listingType.
  3. Set Maximum Listings and Maximum Pages per Location to control run size and cost.
  4. Click Start. Download the dataset as JSON, CSV or Excel, or read it through the API.

Houses for sale in Toronto, with price and bed/bath filters:

{
"mode": "location",
"locations": [{ "city": "Toronto", "province": "ON" }],
"listingType": "buy",
"propertySearchCategory": "residential",
"buildingTypeFilter": "house",
"priceMin": 500000,
"priceMax": 1500000,
"bedroomsMin": 3,
"bathroomsMin": 2,
"maxListings": 100
}

Condos for rent across two cities:

{
"mode": "location",
"locations": [
{ "city": "Vancouver", "province": "BC" },
{ "city": "Calgary", "province": "AB" }
],
"listingType": "rent",
"propertySearchCategory": "condo",
"maxListings": 50
}

Recently sold listings in the last 90 days:

{
"mode": "location",
"locations": [{ "city": "Montreal", "province": "QC" }],
"listingType": "sold",
"soldWithinDays": "90days",
"maxListings": 200
}

Paste a search URL refined on the site:

{
"mode": "url",
"urls": [
"https://www.realtor.ca/map#ZoomLevel=11&Center=43.718245%2C-79.376682&LatitudeMax=43.86034&LongitudeMax=-79.12303&LatitudeMin=43.57584&LongitudeMin=-79.63033&view=list&Sort=6-D&PGeoIds=g30_dpz89rm7&GeoName=Toronto%2C%20ON&PropertyTypeGroupID=1&TransactionTypeId=2&PropertySearchTypeId=1&Currency=CAD&IncludeHiddenListings=false",
"https://www.realtor.ca/on/toronto/real-estate"
]
}

Supported URL shapes

ShapeExampleBehaviour
Map search URLhttps://www.realtor.ca/map#ZoomLevel=11&LatitudeMax=...Searches the exact area and filters in the URL.
City pagehttps://www.realtor.ca/on/toronto/real-estateSearches the built-in area for that city (the same cities as Location mode); a city not in the list is skipped with a warning.
Single listing page (/real-estate/<id>/<slug>)not supportedSkipped with a warning; use a search URL. The listing-detail endpoint refused (HTTP 403) every request from a cleared session when tested, so a single page cannot be fetched reliably.

City rent pages (realtor.ca/<province>/<city>/apartments-for-rent) are supported for the same built-in cities and search rentals; their rows come back with listingType set to rent and the rent in price (for example $3,400/Monthly, with the cadence in price.period). Single-listing pages and province landing pages (no listing cards) are not searched. Any URL that is not one of the supported shapes is skipped with a warning in the run log; it never falls back to a default search area. URL mode with the URLs field left empty searches two default areas in order, a Toronto map search and then the Vancouver city page (the Console form is prefilled with those two plus a Toronto rent page), and stops as soon as Max listings is reached. With the default Max listings (20) the Toronto map search alone fills the limit, so raise Max listings (or edit the URLs) to reach the Vancouver page.

Dataset views

The dataset has five ready-made tables: Overview (price, address, key features), Agents & Brokerages, Media & Open House, Changes (incremental) and Details (community, status, ownership and building type). Turn on Flat output for one-level records.

Cities with built-in coordinates

Location mode has a built-in, precise search area for 33 major Canadian cities (Toronto, Vancouver, Montreal, Calgary, Edmonton, Ottawa, Winnipeg, Halifax and more). Any other city is searched using a default area in southern Ontario plus the city and province name as a search term, so cities outside southern Ontario may return few or unrelated listings. For those, and for an exact area anywhere in Canada, draw it on the site and use URL mode instead.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/realtor-ca-scraper").call(run_input={
"mode": "location",
"locations": [{"city": "Toronto", "province": "ON"}],
"listingType": "buy",
})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["address"]["full"], listing["price"]["display"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/realtor-ca-scraper').call({
mode: 'location',
locations: [{ city: 'Toronto', province: 'ON' }],
listingType: 'buy',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume, Incremental mode and Checkpoint

Three independent controls that are easy to mix up:

  • Resume from run/dataset ID continues ONE interrupted crawl: paste its run or dataset ID and this run skips every listing it already collected, so you don't pay twice.
  • Incremental mode remembers a recurring search between separate scheduled runs. Each listing is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only after a run that scans the whole search, and only with emitExpired on). stateKey names or shares the stored baseline. Use Ignore fields when detecting changes to name fields that should never trigger UPDATED; the relative "time on realtor.ca" text is ignored by default.
  • Resume from Checkpoint continues THIS SAME run after a platform migration or restart. It is on by default and does not change billing or output shape.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each listing, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where listing pages should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringlocationSearch mode: location (city and province, plus filters) or url (paste Realtor.ca search URLs).
locationsarray(none; prefilled with Toronto, ON)Cities to search in Location mode. Each entry needs a city and a two-letter province code, e.g. ON.
listingTypestringbuybuy (for sale), rent, or sold.
propertySearchCategorystringresidentialProperty category: residential, commercial, condo, multi-family, vacant-land, recreational, agriculture, or parking.
buildingTypeFilterstring(none)Optional building type within the selected category: house, row-townhouse, or apartment. Location mode only.
priceMininteger(none)Minimum price in CAD. Location mode only.
priceMaxinteger(none)Maximum price in CAD. Location mode only.
bedroomsMininteger(none)Minimum bedrooms, 0 to 10. Location mode only.
bedroomsMaxinteger(none)Maximum bedrooms, 0 to 10. Location mode only; applies only together with bedroomsMin.
bathroomsMininteger(none)Minimum bathrooms, 0 to 10. Location mode only.
sortBystring6-D (Newest)Sort order: Newest, Oldest, Lowest Price, or Highest Price.
soldWithinDaysstring1yearDate range for sold listings: 7days, 14days, 30days, 90days, 6months, or 1year.
openHouseOnlybooleanfalseOnly return listings with an upcoming open house. Location mode only.
keywordsstring(none)Not currently applied to Location mode searches, which always search by city and province. To search by keyword, add it on Realtor.ca and paste the URL in URL mode.
urlsarrayone map search URL (Toronto) and one city page URL (Vancouver)Realtor.ca map search URLs or city pages, used in URL mode.
maxListingsinteger20Stop after this many listings (0 = unlimited).
maxPagesinteger0Maximum search result pages per location, about 12 listings each (0 = every page, with a hard cap of 1000 pages per location).
proxyConfigurationobjectApify residential proxy, country CAConnection settings.
resumeFromRunIdstring(none)Paste a previous run or dataset ID to continue one interrupted crawl, skipping listings it already collected.
incrementalModebooleanfalseTrack a recurring search across scheduled runs and classify each listing as NEW, UPDATED, REAPPEARED, EXPIRED or UNCHANGED.
stateKeystring(none)Optional label for the Incremental mode baseline; auto-derived from your search when left empty.
emitUnchangedbooleanfalseIncremental mode: also return (and bill) listings with no changes.
simplifyOutputbooleanfalseReturn flat records (addressCity, priceValue, featuresBedrooms, first agent as agentName/agentPhone) instead of nested objects. Same listings and billing.
emitExpiredbooleanfalseIncremental mode: also return (and bill) listings that disappeared, once, after a complete scan.
ignoreFieldsForChangesarray[]Incremental mode: field names that never make a listing UPDATED (matched at any nesting depth, still returned in the output). timeOnRealtor, its mirrored entries in tags and scrapedAt are always ignored because they change every run.
resumeFromCheckpointbooleantrueResume this same run from its last checkpoint after a platform migration or restart.
mcpConnectorsarray(none)Optional: send a summary of each listing to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which listing pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"propertyId": "12345678",
"mlsNumber": "C1234567",
"url": "https://www.realtor.ca/listing/12345678/100-sample-street-toronto",
"listingType": "buy",
"propertyType": "condo",
"buildingType": "Apartment",
"ownershipType": "Condominium/Strata",
"dateListed": "2026-03-19T10:00:00.000Z",
"timeOnRealtor": "2 hours ago",
"tags": ["Open House"],
"address": {
"full": "100 SAMPLE STREET|Toronto, Ontario M5A 1A1",
"street": "100 SAMPLE STREET",
"city": "Toronto",
"province": "Ontario",
"postalCode": "M5A1A1"
},
"coordinates": {
"latitude": 43.65,
"longitude": -79.38
},
"price": {
"display": "$850,000",
"value": 850000
},
"features": {
"bedrooms": 2,
"bathrooms": 2,
"parkingSpaces": 1,
"parkingType": "Underground, Garage",
"buildingSize": "90 m2"
},
"propertyFeatures": [
"Storage locker",
"Floor Area: 900+ sqft",
"Parking: Underground, Garage"
],
"media": {
"imageCount": 1,
"images": ["https://cdn.realtor.ca/listings/sample/highres/1/sample_1.jpg"]
},
"agents": [
{
"name": "Sample Agent",
"phone": "(416) 555-0100",
"position": "Broker of Record",
"profileUrl": "https://www.realtor.ca/agent/100001/sample-agent",
"organization": "Sample Realty Inc.",
"organizationId": "100200",
"organizationDesignation": "Brokerage",
"organizationWebsite": "http://www.example-realty.ca/",
"organizationPhone": "(416) 555-0200"
}
],
"scrapedAt": "2026-03-19T12:00:00.000Z"
}

Plan Requirement

This site refuses datacenter connections and plain scripted requests, so the actor needs Apify residential proxies with country Canada (the default). Datacenter proxies are not expected to work: the run log says "Using a datacenter proxy. This site usually refuses datacenter connections. Use the default RESIDENTIAL proxy with country CA for reliable runs." Residential proxies are not included in the Apify free plan. Leave Proxy configuration at its default. The actor retries and rotates connections when one is refused, and stops early (keeping what it collected) with "Too many consecutive upstream refusals, stopping this run early" when the site keeps refusing.

FAQ

How much does it cost?

You pay per listing returned. The Pricing tab on the actor page shows the current rate. Use Maximum Listings to cap the size, and cost, of any run.

This actor collects only publicly available property listing data. You are responsible for how you use it: follow Realtor.ca's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Agent and brokerage names are included because that information is published alongside each listing.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run classifies every listing as NEW, UPDATED, REAPPEARED, EXPIRED or UNCHANGED against the last committed run for that search, and unchanged listings are not billed unless you turn on Emit unchanged listings.

What is the difference between Resume from run/dataset ID, Incremental mode, and Resume from Checkpoint?

They solve three different problems. Resume from run/dataset ID continues one specific interrupted run so you don't rescrape listings it already collected. Incremental mode tracks the same search across separate scheduled runs and reports what changed. Resume from Checkpoint (on by default) simply lets one run recover its own progress after a platform migration or restart. Use any combination, or none.

Why did my run fail instead of returning an empty dataset?

Apart from invalid input or a resume ID that can't be read, the run fails only when nothing could be collected and the site could not be reached at all: either connection setup was rejected on every available proxy tier, or a search's result page never came back readable. In that case it exits with an error and a clear status message; wait a few minutes and try again, or switch Connection to residential with country CA. If the site was reachable but genuinely has no listings matching your search and filters, the run finishes successfully with an empty dataset and a "No results found" status message instead.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push listing summaries into Notion, Linear or Airtable.

🔗 Want more Realtor data?

Pair this actor with these related scrapers from the same team:

🏠 Realtor.com
From $0.9/1K. Extract property listings from realtor.com. Get comprehensive data...
🧩 Homes.com Scraper
Scrape US property records from Homes.com. Pick a city, state or ZIP and a channel (for...
🏠 Real Estate AU
Extract detailed Australian real estate property listings with 30+ structured fields...
🏠 Trulia Scraper
Scrape Trulia.com property listings by location, filters, or URL. Extract prices, beds...
🏠 Homes.co.nz Scraper
Scrape Homes.co.nz listings by location or URL with pagination. Extract property details...
🏠 Crexi Scraper
Scrape crexi.com commercial listings: asking price, cap rate, square footage, units, year...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.