Realtor.ca at a glance
Realtor.ca is a ready-to-run Apify actor from abotapi for collecting real estate data. Its documented output includes id, mls #, type, property and address, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.83 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Real Estate, Automation, Developer Tools
- Region
- North America
- Pricing
- $2.83 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 27 options
From $1/1K. Scrape Realtor.ca property listings with prices, descriptions, images, agent and brokerage details, coordinates, open house times, building features, and more.
What Realtor.ca can do
- 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.
Choose what to collect
These inputs let you configure Realtor.ca - Property Listings, Prices, Agents & Open Houses. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring | Location mode = pick city + province + filters below. URL mode = paste any realtor.ca search URL already refined in a browser (recommended for complex filters like map area, building type, exact bed/bath ranges). |
locationsarray | Locations to search. Province is optional - leave it blank to use the city's default. Example: Toronto / ON. |
listingTypestring | Type of property listings to scrape. |
propertySearchCategorystring | Property search category. Determines the type of properties returned. |
buildingTypeFilterstring | Filter by specific building type (optional, works within the selected Property Category) |
priceMininteger | Minimum property price (CAD) |
priceMaxinteger | Maximum property price (CAD) |
Show 20 more inputs
| Input | What it controls |
|---|---|
bedroomsMininteger | Minimum number of bedrooms |
bedroomsMaxinteger | Maximum number of bedrooms |
bathroomsMininteger | Minimum number of bathrooms |
sortBystring | Sort order for search results. Default is 'Newest' (date listed, newest first). |
soldWithinDaysstring | Date range for sold listings. Only applies when Listing Type is 'Sold'. |
openHouseOnlyboolean | Only return listings with upcoming open houses |
keywordsstring | Additional search keywords (e.g. 'pool', 'waterfront', 'garage') |
urlsarray | Realtor.ca URLs to scrape, one search per URL. Supported: a map search URL (open realtor.ca, apply filters or draw the area, copy the address bar) and a city page (realtor.ca///real-estate or /apartments-for-rent, for the cities in the built-in list). Single-listing pages and other URLs are skipped with a warning. Searched in order; the run stops once Max listings is reached, so with the default limit only the first URL may be scraped. |
maxListingsinteger | Stop after scraping this many listings. Set to 0 for unlimited. |
maxPagesinteger | Maximum search result pages to process per location. Each page has ~12 results. Set to 0 for the default (every page the search has, up to a hard cap of 1000 pages per location). |
resumeFromCheckpointboolean | Continue this SAME run after a platform migration or restart, reloading its own in-progress state. Different from 'Resume from run/dataset ID' above, which continues a separate, already-finished run. |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to skip listings it already collected and only scrape new ones - useful for continuing an interrupted crawl. Leave empty for a normal fresh run. For recurring/scheduled monitoring of the same search instead, use Incremental mode below. |
incrementalModeboolean | When ON, the actor remembers this search's results between separate runs and classifies each listing as NEW / UPDATED / REAPPEARED / EXPIRED / UNCHANGED (see the dataset's changeType field). Off by default so existing scheduled runs are unaffected. Distinct from 'Resume from run/dataset ID' above, which continues one specific interrupted run instead of tracking recurring changes. |
stateKeystring | Optional label for the saved baseline Incremental mode uses. Leave empty to auto-derive one from your search mode and filters, so two differently-configured searches never share a baseline. Set your own label to track multiple named campaigns, or to intentionally share a baseline across differently-configured runs. |
emitUnchangedboolean | When ON, listings with no changes since the last run are still returned (changeType=UNCHANGED) and billed as a normal result. Off by default so a recurring run only returns and bills for what actually changed. |
emitExpiredboolean | When ON, listings tracked by a previous Incremental mode run that no longer appear are returned once as changeType=EXPIRED and billed as a normal result. Only fires after a run that scans this search's full result set (no page/item cap hit, not a resumed run). Off by default. |
ignoreFieldsForChangesarray | Output field names that should NOT make a listing count as UPDATED, even when they changed. By default the relative 'time on realtor.ca' text (timeOnRealtor, and the matching entries in tags) and scrapedAt are ignored automatically because they change every run. Add any other field name here, for example price or media. Matches a field name at any nesting depth. Ignored fields are still returned in the output. |
mcpConnectorsarray | Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
propertyIdID (text)mlsNumberMLS # (text)listingTypeType (text)propertyTypeProperty (text)addressAddress (object)pricePrice (object)featuresFeatures (object)urlURL (link)agentsAgents (object)mediaMedia (object)openHouseOpen House (object)changeTypeChange (text)Show 7 more fields
changedFieldsChanged fields (array)firstSeenAtFirst seen (date)lastSeenAtLast seen (date)communityNameCommunity (text)statusIdStatus (number)ownershipTypeOwnership (text)buildingTypeBuilding (text)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"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"
}Ways to use this data
- 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.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Realtor.ca return?
The documented output for Realtor.ca includes id, mls #, type, property, address, price, features and url. Availability of each field depends on the source page and the selected mode.
How much does Realtor.ca cost?
It costs $2.83 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
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.
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.
