# Realtor.CA Commercial Scraper | Enterprise Grade (`fatihtahta/realtor-canada-scraper-commercial`) Actor

Extract structured Canada commercial real estate listings from Realtor.ca with property signals, seller details, media assets, contact data and more. Built for enterprise-grade Canada commercial property intelligence, listing monitoring, lead enrichment and automated analytics pipelines.

- **URL**: https://apify.com/fatihtahta/realtor-canada-scraper-commercial.md
- **Developed by:** [Fatih Tahta](https://apify.com/fatihtahta) (community)
- **Categories:** Real estate, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Realtor.ca Commercial Scraper

**Slug:** `fatihtahta/realtor-ca-commercial-scraper`

### Overview

Realtor.ca Commercial Scraper collects structured commercial property listing records from Realtor.ca, including listing identity, pricing, location, building and land attributes, broker and agent contacts, media, listing status, and source provenance. [Realtor.ca](https://www.realtor.ca/) is one of Canada's primary real estate listing portals, making its commercial listing data useful for market analysis, lead generation, competitive monitoring, and operational reporting. The actor turns public listing pages and search results into repeatable JSON records that are easier to load into analytics tools, CRMs, data warehouses, and enrichment workflows. It is designed for consistent recurring data acquisition across Canadian locations, deal types, and commercial property segments. Results reflect the public data available at run time and should be validated against your own business rules before production use.

### Why Use This Actor

- **Market research and analytics teams:** Build structured extraction workflows for pricing, availability, geographic distribution, property types, and listing status.
- **Product and content teams:** Populate internal tools, content databases, and market pages with normalized commercial listing attributes.
- **Developers and data engineering teams:** Feed downstream systems with predictable JSON records suitable for ETL, warehouse ingestion, and API-backed applications.
- **Lead generation and enrichment teams:** Create targeted prospect lists from public listings, agents, brokerages, property categories, and locations.
- **Monitoring and competitive intelligence teams:** Schedule recurring runs to observe market movement, new listings, sold records, lease inventory, and category-level changes.

### Common Use Cases

- **Market intelligence:** Monitor commercial supply, pricing, listing status, and location coverage across Canadian markets.
- **Lead generation:** Build targeted prospect datasets from public commercial listings, agents, and brokerage records.
- **Competitive monitoring:** Track changes in commercial inventory by property type, geography, deal type, and listing recency.
- **Catalog and directory building:** Populate internal databases with normalized commercial property records and contact metadata.
- **Data enrichment:** Add current public listing details to existing CRM, BI, or market research datasets.
- **Recurring reporting:** Schedule periodic runs for dashboards, alerts, trend analysis, and operational reporting.

### Quick Start

1. Enter a Canadian `location`, such as `Ottawa, Ontario`, `Toronto`, `Vancouver`, or `Nova Scotia`.
2. Choose a `deal_type`: `sale`, `lease`, or `sold`.
3. Set a small `limit`, such as `25`, for your first validation run.
4. Run the actor in Apify Console.
5. Inspect the first dataset records to confirm the fields match your workflow.
6. Increase `limit`, add filters, enable broader coverage, or schedule the actor after validating the output.

### Input Parameters

This actor accepts one required location and optional commercial listing filters for deal type, property category, price, land size, building size, date, keyword, sort order, coverage, and output limit.

| Parameter | Type | Description | Default |
| --- | --- | --- | --- |
| `location` | string | Canadian location to search. Use a city, province, neighborhood, or city with province, such as `Ottawa, Ontario`. Required. | `Ottawa, Ontario` prefill |
| `deal_type` | string | Listing category. Allowed values: `sale`, `lease`, `sold`. | `sale` |
| `sold_within_days` | string | Sold listing recency window. Used only when `deal_type` is `sold`. Allowed values: `all`, `7`, `14`, `30`, `90`, `180`, `365`. | `365` |
| `property_type` | string | Commercial property category. Allowed values: `business`, `multi_family`, `retail`, `industrial`, `office`, `vacant_land`, `agriculture`, `hospitality`, `institutional`. | - |
| `publication_date` | string | Earliest publication date for listings, formatted as a date value. Leave empty to include listings regardless of publication date. | - |
| `keyword` | string | Keyword or phrase to match against listing text. Leave empty when no text filter is needed. | - |
| `min_price` | integer | Minimum asking price in CAD. Applies to sale and sold listings; ignored for lease searches. | - |
| `max_price` | integer | Maximum asking price in CAD. Applies to sale and sold listings; ignored for lease searches. | - |
| `exterior_building_size` | string | Exterior building size range. Allowed values: `0-5000`, `5001-10000`, `10001-15000`, `15001-20000`, `20001-25000`, `25001-30000`, `30001-35000`, `35001-40000`, `40001-45000`, `45001-50000`, `50001-75000`, `75001-100000`, `100001-150000`, `150001-200000`, `200001-250000`, `250001-0`. Values represent square feet. | - |
| `min_land_area` | number | Minimum land area in acres. | - |
| `max_land_area` | number | Maximum land area in acres. | - |
| `min_year_built` | string | Earliest year built. Allowed values: `2026`, `2025`, `2024`, `2023`, `2022`, `2021`, `2020`, `2019`, `2018`, `2017`, `2016`, `2015`, `2010`, `2005`, `2000`, `1990`, `1980`, `1970`, `1960`, `1950`, `1940`, `1930`, `1920`, `1910`, `1900`. | - |
| `max_year_built` | string | Latest year built. Allowed values match `min_year_built`. | - |
| `min_property_tax` | string | Minimum annual property tax amount. Allowed values: `250`, `500`, `1000`, `2000`, `3000`, `4000`, `5000`, `6000`, `8000`, `10000`, `20000`. | - |
| `max_property_tax` | string | Maximum annual property tax amount. Allowed values match `min_property_tax`. | - |
| `min_maintenance_fee` | string | Minimum monthly maintenance fee. Allowed values: `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `1000`, `1500`, `2000`. | - |
| `max_maintenance_fee` | string | Maximum monthly maintenance fee. Allowed values match `min_maintenance_fee`. | - |
| `sort_option` | string | Listing order. Allowed values: `date_desc`, `date_asc`, `price_asc`, `price_desc`, `open_houses_first`, `more_photos_first`, `virtual_tour_first`. | `date_desc` |
| `maximize_coverage` | boolean | When enabled, collects more matching listings for broad searches while respecting filters and `limit`. Disable for faster exploratory runs. | `true` |
| `limit` | integer | Maximum number of listing records to save. Minimum value is `1`. | `100` prefill |

### Choosing Inputs

Use `location` as the primary scope control. Specific locations such as neighborhoods or city-province combinations produce more targeted datasets, while broader provinces or large metro areas improve discovery. Use `deal_type` to separate sale, lease, and sold workflows; this is especially useful when syncing results into downstream systems with different business rules.

Filters such as `property_type`, `keyword`, `publication_date`, price, land area, building size, year built, property tax, and maintenance fee narrow the dataset. Broader filters are better for discovery, while narrower filters are better for repeatable reporting and segmented monitoring. Start with a small `limit` to verify the output shape and then increase it once the first records match your use case. Use `sort_option` when the order of collected listings matters, such as newest listings first or price-based review.

### Example Inputs

#### Scenario: Lease listings in Ottawa

```json
{
  "location": "Ottawa, Ontario",
  "deal_type": "lease",
  "property_type": "multi_family",
  "limit": 50,
  "sort_option": "date_desc",
  "maximize_coverage": false
}
````

#### Scenario: Sold retail properties in Toronto

```json
{
  "location": "Toronto, Ontario",
  "deal_type": "sold",
  "sold_within_days": "90",
  "property_type": "retail",
  "min_price": 500000,
  "max_price": 5000000,
  "limit": 100,
  "sort_option": "price_desc"
}
```

#### Scenario: Targeted office discovery in Vancouver

```json
{
  "location": "Vancouver, British Columbia",
  "deal_type": "sale",
  "property_type": "office",
  "publication_date": "2026-05-01",
  "keyword": "medical",
  "min_land_area": 0.25,
  "limit": 75,
  "maximize_coverage": true
}
```

### Output

#### 9.1 Output destination

The actor writes results to an Apify dataset as JSON records. The dataset is designed for direct consumption by analytics tools, ETL pipelines, and downstream APIs with minimal post-processing.

The output shape documented below represents commercial listing records. Sale, lease, and sold records share the same general envelope, with optional fields appearing based on the data publicly available for each listing type.

#### 9.2 Record envelope and stable identifiers

Each record represents one commercial property listing. The strongest recommended idempotency key is `id`; use `url` as a secondary key when `id` is unavailable, and use a composite key such as `mls_number + url` only when required by your downstream system. For deduplication and upserts, store the recommended key in your destination table or CRM and update the existing record when the same key appears again. Stable identifiers make records easier to merge, deduplicate, and sync across repeated runs. The `source_context.source_url` field provides source provenance for the run context that produced the record.

#### 9.3 Examples

Example: sale listing (`source_context.deal_type = "sale"`)

```json
{
  "id": "29708926",
  "mls_number": "X13090702",
  "url": "https://www.realtor.ca/real-estate/29708926/242-victoria-street-mississippi-mills-911-almonte",
  "title": "242 VICTORIA STREET, Mississippi Mills, Ontario K0A1A0",
  "property_type": "Vacant Land",
  "description": "Build your dream home on this prime vacant lot at 242 Victoria Street in the heart of charming Almonte. Measuring approximately 63.92 x 70.19 feet, this property is ideally situated on a quiet, family-friendly residential street. Enjoy the perfect blend of small-town charm and everyday convenience, with a short walk to local amenities, schools, parks, playgrounds, and shopping. Whether you're looking to create your forever home or invest in a growing community, this is a rare opportunity to secure your own piece of land in a sought-after location. (42799628)",
  "pricing": {
    "display_price": "$159,900",
    "amount": 159900,
    "currency": "CAD",
    "short_value": "160K"
  },
  "location": {
    "address": "242 VICTORIA STREET, Mississippi Mills, Ontario K0A1A0",
    "postal_code": "K0A1A0",
    "province": "Ontario",
    "coordinates": {
      "latitude": 45.2320579,
      "longitude": -76.1911795
    },
    "permit_show_address": true
  },
  "details": {
    "property_type_id": "303",
    "building": {
      "bathroom_total": "0"
    },
    "land": {
      "size_total": "65.98 x 63.55 FT",
      "size_frontage": "65 ft ,11 in"
    }
  },
  "contacts": {
    "agents": [
      {
        "id": "2002748",
        "name": "Paul Schnittker",
        "first_name": "Paul",
        "last_name": "Schnittker",
        "position": "Salesperson",
        "photo_url": "https://cdn.realtor.ca/individuals/TS637708395000000000/highres/1285716.jpg",
        "profile_url": "https://www.realtor.ca/agent/2002748/paul-schnittker-66-mill-st-almonte-ontario-k0a1a0",
        "phones": [
          {
            "type": "Telephone",
            "number": "613-256-7285",
            "area_code": "613",
            "phone_type_id": "1"
          }
        ],
        "websites": [
          {
            "url": "http://www.ubettercallpaul.ca/",
            "website_type_id": "1"
          }
        ],
        "email_contacts": [
          {
            "contact_id": "577972188"
          }
        ],
        "organization": {
          "id": "291601",
          "name": "EXP REALTY",
          "type": "Firm",
          "designation": "Brokerage",
          "address": {
            "address": "66 MILL ST, ALMONTE, Ontario K0A1A0",
            "permit_show_address": true
          },
          "phones": [
            {
              "type": "Telephone",
              "number": "866-530-7737",
              "area_code": "866",
              "phone_type_id": "1"
            }
          ],
          "websites": [
            {
              "url": "http://exprealty.ca/",
              "website_type_id": "1"
            }
          ],
          "email_contacts": [
            {
              "contact_id": "577980330"
            }
          ],
          "profile_url": "https://www.realtor.ca/office/firm/291601/exp-realty-66-mill-st-almonte-ontario-k0a1a0",
          "has_email": true,
          "permit_free_text_email": true,
          "permit_show_listing_link": true,
          "photo_last_updated": "2026-04-24T01:50:00"
        },
        "agent_photo_last_updated": "2021-10-26T10:05:00",
        "permit_free_text_email": true,
        "permit_show_listing_link": true,
        "corporation_display_type_id": "0",
        "review_keys": {
          "real_satisfied": "Paul-Schnittker-1"
        }
      }
    ],
    "brokerages": [
      {
        "id": "291601",
        "name": "EXP REALTY",
        "type": "Firm",
        "designation": "Brokerage",
        "address": {
          "address": "66 MILL ST, ALMONTE, Ontario K0A1A0",
          "permit_show_address": true
        },
        "phones": [
          {
            "type": "Telephone",
            "number": "866-530-7737",
            "area_code": "866",
            "phone_type_id": "1"
          }
        ],
        "websites": [
          {
            "url": "http://exprealty.ca/",
            "website_type_id": "1"
          }
        ],
        "email_contacts": [
          {
            "contact_id": "577980330"
          }
        ],
        "profile_url": "https://www.realtor.ca/office/firm/291601/exp-realty-66-mill-st-almonte-ontario-k0a1a0",
        "has_email": true,
        "permit_free_text_email": true,
        "permit_show_listing_link": true,
        "photo_last_updated": "2026-04-24T01:50:00"
      }
    ]
  },
  "media": {
    "images": [
      {
        "sequence": 1,
        "high_res_url": "https://cdn.realtor.ca/listings/TS639136727810130000/reb76/highres/2/x13090702_1.jpg",
        "medium_res_url": "https://cdn.realtor.ca/listings/TS639136727810130000/reb76/medres/2/x13090702_1.jpg",
        "low_res_url": "https://cdn.realtor.ca/listings/TS639136727810130000/reb76/lowres/2/x13090702_1.jpg",
        "last_updated": "2026-05-06T13:59:41",
        "type_id": "0"
      }
    ],
    "videos": [
      {
        "category_id": "2",
        "url": "https://www.youtube.com/watch?v=KRiyToksxow",
        "description": "VideoTourWebsite",
        "order": 1,
        "video_type": "Youtube"
      }
    ]
  },
  "status": {
    "id": "1",
    "time_on_realtor": "1 day ago",
    "tags": [
      {
        "label": "1 day ago",
        "listing_tag_type_id": "1"
      }
    ]
  },
  "source_context": {
    "seed_id": "7cb78a2f9284",
    "seed_type": "query",
    "seed_value": "Ottawa, Ontario",
    "deal_type": "sale",
    "page_index": 1,
    "source_url": "https://www.realtor.ca/map?view=list&SearchText=Ottawa%2C%20Ontario"
  },
  "source_details": {
    "relative_urls": {
      "details": "/real-estate/29708926/242-victoria-street-mississippi-mills-911-almonte",
      "english": "/real-estate/29708926/242-victoria-street-mississippi-mills-911-almonte",
      "french": "/immobilier/29708926/242-victoria-street-mississippi-mills"
    },
    "historical_data_is_cleared": false,
    "timestamps": {
      "photo_changed": "2026-05-06T17:59:41",
      "inserted": "2026-05-06T16:54:50.383000+00:00",
      "data_prep_inserted": "2026-05-06T16:56:04.747000+00:00"
    },
    "uploaded_by": "76"
  }
}
```

Example: lease listing (`source_context.deal_type = "lease"`)

```json
{
  "id": "29720628",
  "mls_number": "X13100392",
  "url": "https://www.realtor.ca/real-estate/29720628/s08-61-parent-avenue-ottawa-4001-lower-townbyward-market",
  "title": "S08 - 61 PARENT AVENUE, Ottawa, Ontario K1N7A7",
  "property_type": "Multi-family",
  "description": "All-Inclusive - Fully furnished - Students/Young professionals STUDIO: AVAILABLE IMMEDIATELY!! Welcome to the newest ALL-INCLUSIVE, fully furnished building in the heart of Ottawa! The property is located 15m walk from University of Ottawa, 5 Minute walk from the Byward Market, across the street from Bruyere Hospital and MUCH MUCH MORE! This affordable yet modern property comes equipped with: Keyfob entry, A/C, WiFi included, On-site laundry, 24/7 Video security, Intercom entry, 3 Communal kitchens. Each unit comes with its very own fridge, sink and microwave-oven, desk and wall mounted TV. Enjoy downtown living at a affordable cost! (42821020)",
  "pricing": {
    "display_price": "$1,350/Monthly",
    "amount": 1350,
    "currency": "CAD",
    "short_value": "1.35K"
  },
  "location": {
    "address": "S08 - 61 PARENT AVENUE, Ottawa, Ontario K1N7A7",
    "postal_code": "K1N7A7",
    "province": "Ontario",
    "coordinates": {
      "latitude": 45.4317778,
      "longitude": -75.6957997
    },
    "permit_show_address": true
  },
  "details": {
    "property_type_id": "310",
    "building": {
      "bathroom_total": "1",
      "size_interior": "464.5113 m2",
      "type": "Other",
      "half_bath_total": "1",
      "floor_area_measurements": [
        {
          "area": "5000+ sqft",
          "area_unformatted": "5000-100000 sqft",
          "type": "Square Footage",
          "measure_unit_id": "1",
          "type_id": "1",
          "source_id": "0",
          "sort_by": "1"
        }
      ]
    },
    "land": {
      "size_total": "33.3 x 198.5 FT",
      "size_frontage": "33 ft ,3 in"
    },
    "parking": {
      "types": [
        {
          "name": "No Garage"
        }
      ],
      "display_text": "No Garage",
      "spaces_total": 0
    }
  },
  "contacts": {
    "agents": [
      {
        "id": "2247806",
        "name": "Ayantu Yeshitla",
        "first_name": "Ayantu",
        "last_name": "Yeshitla",
        "position": "Salesperson",
        "profile_url": "https://www.realtor.ca/agent/2247806/ayantu-yeshitla-2148-carling-ave-unit-6-ottawa-ontario-k2a1h1",
        "phones": [
          {
            "type": "Telephone",
            "number": "613-829-1818",
            "area_code": "613",
            "phone_type_id": "1"
          }
        ],
        "email_contacts": [
          {
            "contact_id": "578027829"
          }
        ],
        "organization": {
          "id": "61051",
          "name": "ROYAL LEPAGE INTEGRITY REALTY",
          "type": "Firm",
          "designation": "Brokerage",
          "logo_url": "https://cdn.realtor.ca/organizations/en-CA/TS639125922000000000/lowres/1125368.jpg",
          "address": {
            "address": "2148 CARLING AVE., UNIT 6, OTTAWA, Ontario K2A1H1",
            "permit_show_address": true
          },
          "phones": [
            {
              "type": "Telephone",
              "number": "613-829-1818",
              "area_code": "613",
              "phone_type_id": "1"
            }
          ],
          "websites": [
            {
              "url": "https://royallepageintegrity.ca/",
              "website_type_id": "1"
            }
          ],
          "email_contacts": [
            {
              "contact_id": "577980491"
            }
          ],
          "profile_url": "https://www.realtor.ca/office/firm/61051/royal-lepage-integrity-realty-2148-carling-ave-unit-6-ottawa-ontario-k2a1h1",
          "has_email": true,
          "permit_free_text_email": true,
          "permit_show_listing_link": true,
          "photo_last_updated": "2026-04-24T01:50:00"
        },
        "permit_free_text_email": true,
        "permit_show_listing_link": true,
        "corporation_display_type_id": "0"
      }
    ],
    "brokerages": [
      {
        "id": "61051",
        "name": "ROYAL LEPAGE INTEGRITY REALTY",
        "type": "Firm",
        "designation": "Brokerage",
        "logo_url": "https://cdn.realtor.ca/organizations/en-CA/TS639125922000000000/lowres/1125368.jpg",
        "address": {
          "address": "2148 CARLING AVE., UNIT 6, OTTAWA, Ontario K2A1H1",
          "permit_show_address": true
        },
        "phones": [
          {
            "type": "Telephone",
            "number": "613-829-1818",
            "area_code": "613",
            "phone_type_id": "1"
          }
        ],
        "websites": [
          {
            "url": "https://royallepageintegrity.ca/",
            "website_type_id": "1"
          }
        ],
        "email_contacts": [
          {
            "contact_id": "577980491"
          }
        ],
        "profile_url": "https://www.realtor.ca/office/firm/61051/royal-lepage-integrity-realty-2148-carling-ave-unit-6-ottawa-ontario-k2a1h1",
        "has_email": true,
        "permit_free_text_email": true,
        "permit_show_listing_link": true,
        "photo_last_updated": "2026-04-24T01:50:00"
      }
    ]
  },
  "media": {
    "images": [
      {
        "sequence": 1,
        "high_res_url": "https://cdn.realtor.ca/listings/TS639138008390270000/reb76/highres/2/x13100392_1.jpg",
        "medium_res_url": "https://cdn.realtor.ca/listings/TS639138008390270000/reb76/medres/2/x13100392_1.jpg",
        "low_res_url": "https://cdn.realtor.ca/listings/TS639138008390270000/reb76/lowres/2/x13100392_1.jpg",
        "last_updated": "2026-05-08T01:33:59",
        "type_id": "0"
      }
    ]
  },
  "status": {
    "id": "1",
    "time_on_realtor": "8 hours ago",
    "has_new_image_update": true,
    "tags": [
      {
        "label": "8 hours ago",
        "listing_tag_type_id": "1"
      }
    ]
  },
  "source_context": {
    "seed_id": "7cb78a2f9284",
    "seed_type": "query",
    "seed_value": "Ottawa, Ontario",
    "deal_type": "lease",
    "page_index": 1,
    "source_url": "https://www.realtor.ca/map?view=list&SearchText=Ottawa%2C%20Ontario"
  },
  "source_details": {
    "relative_urls": {
      "details": "/real-estate/29720628/s08-61-parent-avenue-ottawa-4001-lower-townbyward-market",
      "english": "/real-estate/29720628/s08-61-parent-avenue-ottawa-4001-lower-townbyward-market",
      "french": "/immobilier/29720628/s08-61-parent-avenue-ottawa"
    },
    "historical_data_is_cleared": false,
    "timestamps": {
      "photo_changed": "2026-05-08T05:33:59",
      "inserted": "2026-05-08T05:33:59.020000+00:00",
      "data_prep_inserted": "2026-05-08T05:36:24.393000+00:00"
    },
    "uploaded_by": "76"
  }
}
```

Example: sold listing (`source_context.deal_type = "sold"`)

```json
{
  "id": "28584704",
  "mls_number": "40749912",
  "url": "https://www.realtor.ca/real-estate/28584704/1226-old-carp-road-kanata",
  "title": "1226 OLD CARP Road, Kanata, Ontario K2K1X7",
  "property_type": "Multi-family",
  "pricing": {
    "display_price": "$745,000",
    "currency": "CAD",
    "short_value": "745K",
    "original_listing": {
      "amount": 798000
    }
  },
  "location": {
    "address": "1226 OLD CARP Road, Kanata, Ontario K2K1X7",
    "postal_code": "K2K1X7",
    "province": "Ontario",
    "coordinates": {
      "latitude": 45.35388116,
      "longitude": -75.94549959
    },
    "permit_show_address": true
  },
  "details": {
    "property_type_id": "310",
    "building": {
      "bathroom_total": "3",
      "bedrooms": "6",
      "size_interior": "2920.0000",
      "stories_total": "1",
      "type": "Triplex",
      "unit_total": "3",
      "floor_area_measurements": [
        {
          "area": "2920 sqft",
          "area_unformatted": "2920 sqft",
          "type": "Square Footage",
          "measure_unit_id": "1",
          "type_id": "1",
          "source_id": "0",
          "sort_by": "1"
        }
      ]
    },
    "land": {
      "size_total": "under 1/2 acre",
      "size_frontage": "100 ft"
    },
    "ownership": {
      "type": "Freehold",
      "group_ids": [
        1
      ]
    }
  },
  "media": {
    "images": [
      {
        "sequence": 1,
        "high_res_url": "https://maps.googleapis.com/maps/api/streetview?location=45.35388116%2C-75.94549959&size=600x400&source=outdoor",
        "medium_res_url": "https://maps.googleapis.com/maps/api/streetview?location=45.35388116%2C-75.94549959&size=256x200&source=outdoor",
        "low_res_url": "https://maps.googleapis.com/maps/api/streetview?location=45.35388116%2C-75.94549959&size=130x95&source=outdoor",
        "last_updated": "2026-04-23T01:03:00",
        "type_id": "1"
      }
    ]
  },
  "status": {
    "id": "2",
    "standard_status_id": "4",
    "is_sold": true,
    "tags": [
      {
        "label": "Sold on 01/07/2026",
        "listing_tag_type_id": "4"
      }
    ]
  },
  "source_context": {
    "seed_id": "7cb78a2f9284",
    "seed_type": "query",
    "seed_value": "Ottawa, Ontario",
    "deal_type": "sold",
    "page_index": 1,
    "source_url": "https://www.realtor.ca/map?view=list&SearchText=Ottawa%2C%20Ontario"
  },
  "source_details": {
    "relative_urls": {
      "details": "/real-estate/28584704/1226-old-carp-road-kanata",
      "english": "/real-estate/28584704/1226-old-carp-road-kanata",
      "french": "/immobilier/28584704/1226-old-carp-road-kanata"
    },
    "historical_data_is_cleared": true,
    "timestamps": {
      "sold_on_realtor": "2026-01-07T22:01:28",
      "sold_close": "2026-01-15T00:00:00",
      "photo_changed": "2025-12-20T17:11:00",
      "inserted": "2025-07-10T03:11:42.980000+00:00",
      "data_prep_inserted": "2025-07-10T03:16:00.847000+00:00"
    },
    "uploaded_by": "14"
  }
}
```

### Field Reference

#### Commercial Listing Record

**id** *(string, optional)*: Stable Realtor.ca listing identifier when available.

**mls\_number** *(string, optional)*: MLS number associated with the listing.

**url** *(string, optional)*: Public Realtor.ca listing URL.

**title** *(string, optional)*: Human-readable listing title, usually based on the public address.

**property\_type** *(string, optional)*: Commercial property category, such as multi-family, retail, office, industrial, business, agriculture, hospitality, institutional, or vacant land.

**description** *(string, optional)*: Public listing remarks or description text.

**pricing.display\_price** *(string, optional)*: Price as displayed publicly.

**pricing.amount** *(integer, optional)*: Numeric price amount when available.

**pricing.currency** *(string, optional)*: Price currency, typically `CAD`.

**pricing.short\_value** *(string, optional)*: Compact price label when provided.

**pricing.original\_listing.display\_price** *(string, optional)*: Original/list price text retained for sold records when available.

**pricing.original\_listing.amount** *(integer, optional)*: Original/list price amount retained for sold records when available.

**pricing.price\_change.time\_on\_realtor** *(string, optional)*: Public price-change timing label when available.

**pricing.price\_change.tag\_date** *(string, optional)*: Price-change date when available.

**location.address** *(string, optional)*: Public address text.

**location.postal\_code** *(string, optional)*: Postal code. Treat as text, not a number.

**location.province** *(string, optional)*: Province name.

**location.coordinates.latitude** *(number, optional)*: Latitude.

**location.coordinates.longitude** *(number, optional)*: Longitude.

**location.permit\_show\_address** *(boolean, optional)*: Whether the source indicates the address may be displayed.

**details.property\_type\_id** *(string, optional)*: Source property type identifier. Treat as an identifier, not a number.

**details.farm\_type** *(string, optional)*: Farm type label when available.

**details.zoning\_type** *(string, optional)*: Zoning type label when available.

**details.building** *(object, optional)*: Building attributes such as bathrooms, bedrooms, size, storeys, building type, unit count, and measurements.

**details.building.bathroom\_total** *(string, optional)*: Total bathrooms as provided by the source.

**details.building.bedrooms** *(string, optional)*: Bedroom count as provided by the source.

**details.building.size\_interior** *(string, optional)*: Interior size value and unit when available.

**details.building.stories\_total** *(string, optional)*: Total storeys when available.

**details.building.type** *(string, optional)*: Building type label.

**details.building.unit\_total** *(string, optional)*: Total unit count when available.

**details.building.floor\_area\_measurements** *(array, optional)*: Floor area measurement records.

**details.building.floor\_area\_measurements.area** *(string, optional)*: Display area value.

**details.building.floor\_area\_measurements.area\_unformatted** *(string, optional)*: Source area range or unformatted value.

**details.building.floor\_area\_measurements.type** *(string, optional)*: Measurement type label.

**details.building.floor\_area\_measurements.measure\_unit\_id** *(string, optional)*: Measurement unit identifier.

**details.building.floor\_area\_measurements.type\_id** *(string, optional)*: Measurement type identifier.

**details.building.floor\_area\_measurements.source\_id** *(string, optional)*: Measurement source identifier.

**details.building.floor\_area\_measurements.sort\_by** *(string, optional)*: Source ordering value.

**details.land** *(object, optional)*: Land and lot attributes.

**details.land.size\_total** *(string, optional)*: Lot or land size display value.

**details.land.size\_frontage** *(string, optional)*: Frontage display value.

**details.ownership.type** *(string, optional)*: Ownership type label.

**details.ownership.group\_ids** *(array, optional)*: Ownership group identifiers when provided.

**details.parking.types** *(array, optional)*: Parking type records.

**details.parking.types.name** *(string, optional)*: Parking type label.

**details.parking.types.spaces** *(integer, optional)*: Parking spaces for that type when available.

**details.parking.display\_text** *(string, optional)*: Public parking summary.

**details.parking.spaces\_total** *(integer, optional)*: Total parking spaces.

**details.nearby\_amenities** *(string, optional)*: Public nearby amenities text when available.

**details.business** *(object, optional)*: Business-specific listing attributes when available.

**contacts.agents** *(array, optional)*: Public agents associated with the listing.

**contacts.agents.id** *(string, optional)*: Agent identifier.

**contacts.agents.name** *(string, optional)*: Agent display name.

**contacts.agents.first\_name / contacts.agents.last\_name** *(string, optional)*: Agent name components.

**contacts.agents.position** *(string, optional)*: Agent role or position.

**contacts.agents.designation** *(string, optional)*: Professional designation when provided.

**contacts.agents.photo\_url** *(string, optional)*: Agent photo URL.

**contacts.agents.profile\_url** *(string, optional)*: Public agent profile URL.

**contacts.agents.phones** *(array, optional)*: Public phone records.

**contacts.agents.phones.type** *(string, optional)*: Phone type label.

**contacts.agents.phones.number** *(string, optional)*: Formatted phone number.

**contacts.agents.phones.area\_code** *(string, optional)*: Phone area code.

**contacts.agents.phones.phone\_type\_id** *(string, optional)*: Phone type identifier.

**contacts.agents.websites** *(array, optional)*: Public website records.

**contacts.agents.websites.url** *(string, optional)*: Website URL.

**contacts.agents.websites.website\_type\_id** *(string, optional)*: Website type identifier.

**contacts.agents.email\_contacts** *(array, optional)*: Public email contact metadata.

**contacts.agents.email\_contacts.contact\_id** *(string, optional)*: Contact identifier.

**contacts.agents.organization** *(object, optional)*: Brokerage or organization associated with the agent.

**contacts.agents.organization.id** *(string, optional)*: Organization identifier.

**contacts.agents.organization.name** *(string, optional)*: Organization name.

**contacts.agents.organization.type** *(string, optional)*: Organization type.

**contacts.agents.organization.designation** *(string, optional)*: Organization designation.

**contacts.agents.organization.logo\_url** *(string, optional)*: Organization logo URL.

**contacts.agents.organization.address.address** *(string, optional)*: Organization address.

**contacts.agents.organization.address.permit\_show\_address** *(boolean, optional)*: Whether the organization address may be displayed.

**contacts.agents.organization.phones** *(array, optional)*: Organization phone records.

**contacts.agents.organization.websites** *(array, optional)*: Organization website records.

**contacts.agents.organization.email\_contacts** *(array, optional)*: Organization email contact metadata.

**contacts.agents.organization.profile\_url** *(string, optional)*: Public organization profile URL.

**contacts.agents.organization.has\_email** *(boolean, optional)*: Whether public email contact is available.

**contacts.agents.organization.permit\_free\_text\_email** *(boolean, optional)*: Public email contact setting.

**contacts.agents.organization.permit\_show\_listing\_link** *(boolean, optional)*: Public listing-link display setting.

**contacts.agents.organization.photo\_last\_updated** *(string, optional)*: Organization photo update timestamp.

**contacts.agents.agent\_photo\_last\_updated** *(string, optional)*: Agent photo update timestamp.

**contacts.agents.permit\_free\_text\_email** *(boolean, optional)*: Public email contact setting.

**contacts.agents.permit\_show\_listing\_link** *(boolean, optional)*: Public listing-link display setting.

**contacts.agents.corporation\_name** *(string, optional)*: Agent corporation name when provided.

**contacts.agents.corporation\_display\_type\_id** *(string, optional)*: Agent display type identifier.

**contacts.agents.review\_keys.rank\_my\_agent** *(string, optional)*: Public review key when available.

**contacts.agents.review\_keys.real\_satisfied** *(string, optional)*: Public review key when available.

**contacts.agents.review\_keys.testimonial\_tree** *(string, optional)*: Public review key when available.

**contacts.brokerages** *(array, optional)*: Deduplicated public brokerage records associated with the listing.

**contacts.brokerages.id** *(string, optional)*: Brokerage identifier.

**contacts.brokerages.name** *(string, optional)*: Brokerage name.

**contacts.brokerages.type** *(string, optional)*: Brokerage type.

**contacts.brokerages.designation** *(string, optional)*: Brokerage designation.

**contacts.brokerages.logo\_url** *(string, optional)*: Brokerage logo URL.

**contacts.brokerages.address.address** *(string, optional)*: Brokerage address.

**contacts.brokerages.address.permit\_show\_address** *(boolean, optional)*: Whether the brokerage address may be displayed.

**contacts.brokerages.phones** *(array, optional)*: Brokerage phone records.

**contacts.brokerages.websites** *(array, optional)*: Brokerage website records.

**contacts.brokerages.email\_contacts** *(array, optional)*: Brokerage email contact metadata.

**contacts.brokerages.profile\_url** *(string, optional)*: Public brokerage profile URL.

**contacts.brokerages.has\_email** *(boolean, optional)*: Whether public email contact is available.

**contacts.brokerages.permit\_free\_text\_email** *(boolean, optional)*: Public email contact setting.

**contacts.brokerages.permit\_show\_listing\_link** *(boolean, optional)*: Public listing-link display setting.

**contacts.brokerages.photo\_last\_updated** *(string, optional)*: Brokerage photo update timestamp.

**open\_houses** *(array, optional)*: Public open house events when available.

**open\_houses.display\_time** *(string, optional)*: Public open house display time.

**open\_houses.start\_time / open\_houses.end\_time** *(string, optional)*: Open house start and end timestamps.

**open\_houses.event\_type\_id** *(string, optional)*: Open house event type identifier.

**media.images** *(array, optional)*: Listing image records.

**media.images.sequence** *(integer, optional)*: Image order.

**media.images.high\_res\_url / media.images.medium\_res\_url / media.images.low\_res\_url** *(string, optional)*: Image URLs at different sizes.

**media.images.svg\_url** *(string, optional)*: SVG image URL when available.

**media.images.description** *(string, optional)*: Image description when available.

**media.images.last\_updated** *(string, optional)*: Image update timestamp.

**media.images.type\_id** *(string, optional)*: Image type identifier.

**media.videos** *(array, optional)*: Video records when available.

**media.videos.category\_id** *(string, optional)*: Media category identifier.

**media.videos.url** *(string, optional)*: Video URL.

**media.videos.description** *(string, optional)*: Video description.

**media.videos.order** *(integer, optional)*: Video order.

**media.videos.video\_type** *(string, optional)*: Video type label.

**media.floor\_plans** *(array, optional)*: Floor plan records when available.

**media.links** *(array, optional)*: Additional public listing links when available.

**status.id** *(string, optional)*: Listing status identifier.

**status.standard\_status\_id** *(string, optional)*: Standardized status identifier when available.

**status.time\_on\_realtor** *(string, optional)*: Public recency label.

**status.has\_new\_image\_update** *(boolean, optional)*: Whether the listing indicates a new image update.

**status.has\_open\_house\_update** *(boolean, optional)*: Whether the listing indicates an open house update.

**status.is\_sold** *(boolean, optional)*: Whether the listing is sold.

**status.conditionally\_sold** *(boolean, optional)*: Whether the listing is conditionally sold.

**status.distance** *(string, optional)*: Distance value when provided by the source context.

**status.tags** *(array, optional)*: Public listing tags.

**status.tags.label** *(string, optional)*: Tag label.

**status.tags.listing\_tag\_type\_id** *(string, optional)*: Tag type identifier.

**source\_context.seed\_id** *(string, optional)*: Stable run seed identifier.

**source\_context.seed\_type** *(string, optional)*: Seed category, such as `query`.

**source\_context.seed\_value** *(string, optional)*: Location or search value that produced the record.

**source\_context.deal\_type** *(string, optional)*: Deal type used for the record, such as `sale`, `lease`, or `sold`.

**source\_context.page\_index** *(integer, optional)*: Result page index associated with the record.

**source\_context.source\_url** *(string, optional)*: Source context URL retained for provenance.

**source\_details.relative\_urls.details** *(string, optional)*: Relative public listing details path.

**source\_details.relative\_urls.english** *(string, optional)*: English relative public listing path.

**source\_details.relative\_urls.french** *(string, optional)*: French relative public listing path.

**source\_details.historical\_data\_is\_cleared** *(boolean, optional)*: Public historical data flag when available.

**source\_details.timestamps.sold\_on\_realtor** *(string, optional)*: Sold timestamp reported by Realtor.ca.

**source\_details.timestamps.sold\_close** *(string, optional)*: Sold close date when available.

**source\_details.timestamps.photo\_changed** *(string, optional)*: Photo change timestamp.

**source\_details.timestamps.open\_house\_inserted** *(string, optional)*: Open house insertion timestamp.

**source\_details.timestamps.conditionally\_sold\_changed** *(string, optional)*: Conditional sold change timestamp.

**source\_details.timestamps.inserted** *(string, optional)*: Listing insertion timestamp.

**source\_details.timestamps.data\_prep\_inserted** *(string, optional)*: Data preparation timestamp.

**source\_details.listing\_time\_zone** *(string, optional)*: Listing time zone when available.

**source\_details.listing\_boundary** *(string, optional)*: Listing boundary label when available.

**source\_details.listing\_gmt\_offset** *(string, optional)*: Listing GMT offset when available.

**source\_details.uploaded\_by** *(string, optional)*: Public uploader label when available.

### Data Quality, Guarantees, And Handling

- **Structured records:** results are normalized into predictable JSON objects for downstream use.
- **Best-effort extraction:** fields may vary by region, session, availability, and UI experiments.
- **Optional fields:** null-check in downstream code before using nested values.
- **Deduplication:** use `id` as the strongest stable key when available, with `url`, `mls_number`, or a composite key as fallbacks.
- **Freshness:** results reflect the publicly available data at run time.
- **Repeated runs:** use the recommended idempotency key when syncing data into warehouses, CRMs, or search indexes.

### Tips For Best Results

- Start with a small `limit` to validate the output shape before scaling up.
- Use one geography, property type, or deal type per run when you need clean segmentation.
- Leave optional filters empty when the goal is broad market discovery.
- Add filters gradually to understand how each field changes coverage.
- Use `deal_type` to keep sale, lease, and sold workflows separate.
- Schedule recurring runs for monitoring workflows instead of relying on manual one-off collection.
- Use stable identifiers such as `id` and `url` for deduplication when storing results over time.

### How to Run on Apify

1. Open the Actor in Apify Console.
2. Configure the available input fields for the target location, deal type, and filters.
3. Set the maximum number of outputs to collect with `limit`.
4. Click **Start** and wait for the run to finish.
5. Open the dataset and inspect the first records.
6. Download results in JSON, CSV, Excel, or other supported formats.

### Scheduling & Automation

#### Scheduling

**Automated Data Collection**

Use schedules to keep commercial listing datasets fresh for monitoring, reporting, and enrichment workflows. Scheduled runs are most useful when the same location, property type, and deal type need to be collected repeatedly.

- Navigate to **Schedules** in Apify Console
- Create a new schedule, such as daily, weekly, or a custom cron interval
- Configure input parameters
- Enable notifications for run completion
- Add webhooks for automated processing

#### Integration Options

- **CRM enrichment:** sync public listing, brokerage, and agent attributes into account, lead, or opportunity records.
- **BI dashboards:** monitor pricing, availability, property type movement, and geographic coverage over time.
- **Data warehouses:** load normalized listing records for historical analysis and operational reporting.
- **Google Sheets or Airtable:** review smaller datasets, qualify leads, and coordinate manual follow-up.
- **Webhooks:** trigger validation, notification, or ingestion workflows after each completed run.
- **Alerts and scheduled reporting:** notify teams when new listings, sold records, or targeted property segments appear.

### Export Formats And Downstream Use

Apify datasets can be exported or consumed by downstream systems for reporting, automation, and application workflows.

- **JSON:** for APIs, applications, and data pipelines
- **CSV or Excel:** for spreadsheet workflows and manual review
- **API access:** for automated ingestion into internal systems
- **BI and warehouses:** for reporting, dashboards, and historical analysis

### Performance

Estimated run times:

- **Small runs (< 1,000 outputs):** ~3-5 minutes
- **Medium runs (1,000-5,000 outputs):** ~5-15 minutes
- **Large runs (5,000+ outputs):** ~15-30 minutes

Execution time varies based on filters, result volume, and how much information is returned per record. Highly filtered runs can finish faster, while broad discovery or detail-rich records may take longer.

### Limitations

- Availability depends on what Realtor.ca publicly exposes at run time.
- Some optional fields may be missing on sparse records or listing types with limited public details.
- Very broad searches may take longer or require a higher `limit` to collect enough records.
- Target-side changes can affect field availability, labels, or naming.
- Regional, account, or availability differences may change visible results.
- Sold, lease, and sale records may expose different pricing, status, and timestamp fields.

### Troubleshooting

- **No results returned:** Check filter combinations, location spelling, property type selection, and whether Realtor.ca has matching public records.
- **Fewer results than expected:** Broaden filters, raise `limit`, or verify that the target location contains enough matching commercial listings.
- **Some fields are empty:** Optional fields depend on what each listing publicly provides.
- **Run takes longer than expected:** Reduce scope, lower `limit` for validation, or split broad collection into smaller market segments.
- **Output changed:** Compare the current output with the field reference and include a small sample when reporting the issue.

### FAQ

**What data does this actor collect?**

It collects public commercial property listing records from Realtor.ca, including identity fields, pricing, location, property attributes, media, status, agent and brokerage contacts, and source provenance.

**Can I filter by location, category, date, price, or other criteria?**

Yes. The actor supports `location`, `deal_type`, `property_type`, `publication_date`, `keyword`, price ranges, land area, exterior building size, year built, property tax, maintenance fee, sort order, coverage, and output limit.

**Why did I receive fewer results than my limit?**

The source may have fewer matching public listings than requested, filters may be narrow, or some listings may not provide enough usable information to save as records.

**Can I schedule recurring runs?**

Yes. Use Apify schedules to run the actor daily, weekly, or on a custom interval for monitoring and reporting workflows.

**How do I avoid duplicates across runs?**

Use `id` as the primary idempotency key. If `id` is unavailable, use `url`, then `mls_number`, or a composite key appropriate for your destination system.

**Can I export the data to CSV, Excel, or JSON?**

Yes. Apify datasets support export formats such as JSON, CSV, Excel, and other formats available in Apify Console.

**Does this actor collect private data?**

It is intended to collect publicly available listing information from Realtor.ca. Users are responsible for ensuring their use of the data complies with applicable laws and terms.

**What should I include when reporting an issue?**

Include the input used, the run ID, expected versus actual behavior, and a small output sample when possible.

### Compliance & Ethics

#### Responsible Data Collection

This actor collects publicly available commercial real estate listing information from Realtor.ca for legitimate business purposes, including:

- **Commercial real estate** research and market analysis
- **Lead generation and enrichment** for public listing, agent, and brokerage workflows
- **Operational reporting and monitoring** for pricing, availability, and market coverage

This section is informational and not legal advice. Users are responsible for confirming that their collection and use of data complies with applicable laws, regulations, and contractual obligations.

#### Best Practices

- Use collected data in accordance with applicable laws, regulations, and the target site's terms
- Respect individual privacy and personal information
- Use data responsibly and avoid disruptive or excessive collection
- Do not use this actor for spamming, harassment, or other harmful purposes
- Follow relevant data protection requirements where applicable, such as GDPR and CCPA

### Support

For help, use the Issues tab or the actor page in Apify Console. Include the input used, with sensitive values redacted if needed; the run ID; expected versus actual behavior; and a small output sample when relevant. Avoid sharing private credentials, proprietary datasets, or unnecessary personal information in support requests.

# Actor input Schema

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

Enter one Canadian location to search. Examples: "Ottawa", "Ottawa, Ontario", "Toronto", "Vancouver", "Nova Scotia", or "Ontario". Broader areas can return more listings, while specific places produce more targeted results.

## `deal_type` (type: `string`):

Choose whether to collect commercial properties for sale, commercial properties for lease, or sold commercial properties. The default category is properties for sale.

## `sold_within_days` (type: `string`):

Limits sold listings to properties sold within the selected timeframe on Realtor.ca. The default is 365 days. Choose All to include sold listings from any date. This filter is automatically ignored for Properties for sale and Properties for lease searches.

## `property_type` (type: `string`):

Restrict results to a Realtor.ca commercial property category. Leave empty to include all available commercial property types.

## `publication_date` (type: `string`):

Only include listings published on or after the selected date. Leave empty to include listings regardless of publication date.

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

Enter keyword text to focus results on listings that match a specific term or phrase. Leave empty when no keyword filter is needed.

## `min_price` (type: `integer`):

Only include sale or sold listings with an asking price at or above this amount. Ignored for Properties for lease searches.

## `max_price` (type: `integer`):

Only include sale or sold listings with an asking price at or below this amount. Ignored for Properties for lease searches.

## `exterior_building_size` (type: `string`):

Restrict results to a Realtor.ca commercial exterior building size range. Leave empty when exterior building size should not narrow the search.

## `min_land_area` (type: `number`):

Only include listings with a land area at or above this many acres. Leave empty when there is no minimum land size.

## `max_land_area` (type: `number`):

Only include listings with a land area at or below this many acres. Leave empty when there is no maximum land size.

## `min_year_built` (type: `string`):

Only include listings built in or after this year. Leave empty when there is no earliest year requirement.

## `max_year_built` (type: `string`):

Only include listings built in or before this year. Leave empty when there is no latest year requirement.

## `min_property_tax` (type: `string`):

Only include listings with annual property tax at or above this amount. Leave empty when there is no minimum annual tax.

## `max_property_tax` (type: `string`):

Only include listings with annual property tax at or below this amount. Leave empty when there is no maximum annual tax.

## `min_maintenance_fee` (type: `string`):

Only include listings with monthly maintenance fees at or above this amount. Leave empty when there is no minimum monthly fee.

## `max_maintenance_fee` (type: `string`):

Only include listings with monthly maintenance fees at or below this amount. Leave empty when there is no maximum monthly fee.

## `sort_option` (type: `string`):

Select the listing order used for the Realtor.ca search results. The default is newest listings first.

## `maximize_coverage` (type: `boolean`):

Keep this enabled for large searches that may exceed the visible-result limit. Turn it off for faster exploratory runs where the first visible set of matching listings is enough.

## `limit` (type: `integer`):

Enter the maximum number of listings to save across the whole run. Leave empty to collect as many matching listings as the run can retrieve.

## Actor input object example

```json
{
  "location": "Ottawa, Ontario",
  "deal_type": "sale",
  "sold_within_days": "365",
  "sort_option": "date_desc",
  "maximize_coverage": true,
  "limit": 100
}
```

# 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 = {
    "location": "Ottawa, Ontario",
    "limit": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("fatihtahta/realtor-canada-scraper-commercial").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 = {
    "location": "Ottawa, Ontario",
    "limit": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("fatihtahta/realtor-canada-scraper-commercial").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "Ottawa, Ontario",
  "limit": 100
}' |
apify call fatihtahta/realtor-canada-scraper-commercial --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fatihtahta/realtor-canada-scraper-commercial",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Realtor.CA Commercial Scraper | Enterprise Grade",
        "description": "Extract structured Canada commercial real estate listings from Realtor.ca with property signals, seller details, media assets, contact data and more. Built for enterprise-grade Canada commercial property intelligence, listing monitoring, lead enrichment and automated analytics pipelines.",
        "version": "0.0",
        "x-build-id": "hIu8FfO4UYbNE3xXv"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fatihtahta~realtor-canada-scraper-commercial/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fatihtahta-realtor-canada-scraper-commercial",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/fatihtahta~realtor-canada-scraper-commercial/runs": {
            "post": {
                "operationId": "runs-sync-fatihtahta-realtor-canada-scraper-commercial",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/fatihtahta~realtor-canada-scraper-commercial/run-sync": {
            "post": {
                "operationId": "run-sync-fatihtahta-realtor-canada-scraper-commercial",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "location"
                ],
                "properties": {
                    "location": {
                        "title": "Search Location",
                        "minLength": 1,
                        "type": "string",
                        "description": "Enter one Canadian location to search. Examples: \"Ottawa\", \"Ottawa, Ontario\", \"Toronto\", \"Vancouver\", \"Nova Scotia\", or \"Ontario\". Broader areas can return more listings, while specific places produce more targeted results."
                    },
                    "deal_type": {
                        "title": "Choose Listing Category",
                        "enum": [
                            "sale",
                            "lease",
                            "sold"
                        ],
                        "type": "string",
                        "description": "Choose whether to collect commercial properties for sale, commercial properties for lease, or sold commercial properties. The default category is properties for sale.",
                        "default": "sale"
                    },
                    "sold_within_days": {
                        "title": "Sold Within",
                        "enum": [
                            "all",
                            "7",
                            "14",
                            "30",
                            "90",
                            "180",
                            "365"
                        ],
                        "type": "string",
                        "description": "Limits sold listings to properties sold within the selected timeframe on Realtor.ca. The default is 365 days. Choose All to include sold listings from any date. This filter is automatically ignored for Properties for sale and Properties for lease searches.",
                        "default": "365"
                    },
                    "property_type": {
                        "title": "Select Property Type",
                        "enum": [
                            "business",
                            "multi_family",
                            "retail",
                            "industrial",
                            "office",
                            "vacant_land",
                            "agriculture",
                            "hospitality",
                            "institutional"
                        ],
                        "type": "string",
                        "description": "Restrict results to a Realtor.ca commercial property category. Leave empty to include all available commercial property types."
                    },
                    "publication_date": {
                        "title": "Set Earliest Publication Date",
                        "type": "string",
                        "description": "Only include listings published on or after the selected date. Leave empty to include listings regardless of publication date."
                    },
                    "keyword": {
                        "title": "Filter by Keyword",
                        "type": "string",
                        "description": "Enter keyword text to focus results on listings that match a specific term or phrase. Leave empty when no keyword filter is needed."
                    },
                    "min_price": {
                        "title": "Set Minimum Price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include sale or sold listings with an asking price at or above this amount. Ignored for Properties for lease searches."
                    },
                    "max_price": {
                        "title": "Set Maximum Price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include sale or sold listings with an asking price at or below this amount. Ignored for Properties for lease searches."
                    },
                    "exterior_building_size": {
                        "title": "Select Exterior Building Size",
                        "enum": [
                            "0-5000",
                            "5001-10000",
                            "10001-15000",
                            "15001-20000",
                            "20001-25000",
                            "25001-30000",
                            "30001-35000",
                            "35001-40000",
                            "40001-45000",
                            "45001-50000",
                            "50001-75000",
                            "75001-100000",
                            "100001-150000",
                            "150001-200000",
                            "200001-250000",
                            "250001-0"
                        ],
                        "type": "string",
                        "description": "Restrict results to a Realtor.ca commercial exterior building size range. Leave empty when exterior building size should not narrow the search."
                    },
                    "min_land_area": {
                        "title": "Set Minimum Land Area (acre)",
                        "minimum": 0,
                        "type": "number",
                        "description": "Only include listings with a land area at or above this many acres. Leave empty when there is no minimum land size."
                    },
                    "max_land_area": {
                        "title": "Set Maximum Land Area (acre)",
                        "minimum": 0,
                        "type": "number",
                        "description": "Only include listings with a land area at or below this many acres. Leave empty when there is no maximum land size."
                    },
                    "min_year_built": {
                        "title": "Set Earliest Year Built",
                        "enum": [
                            "2026",
                            "2025",
                            "2024",
                            "2023",
                            "2022",
                            "2021",
                            "2020",
                            "2019",
                            "2018",
                            "2017",
                            "2016",
                            "2015",
                            "2010",
                            "2005",
                            "2000",
                            "1990",
                            "1980",
                            "1970",
                            "1960",
                            "1950",
                            "1940",
                            "1930",
                            "1920",
                            "1910",
                            "1900"
                        ],
                        "type": "string",
                        "description": "Only include listings built in or after this year. Leave empty when there is no earliest year requirement."
                    },
                    "max_year_built": {
                        "title": "Set Latest Year Built",
                        "enum": [
                            "2026",
                            "2025",
                            "2024",
                            "2023",
                            "2022",
                            "2021",
                            "2020",
                            "2019",
                            "2018",
                            "2017",
                            "2016",
                            "2015",
                            "2010",
                            "2005",
                            "2000",
                            "1990",
                            "1980",
                            "1970",
                            "1960",
                            "1950",
                            "1940",
                            "1930",
                            "1920",
                            "1910",
                            "1900"
                        ],
                        "type": "string",
                        "description": "Only include listings built in or before this year. Leave empty when there is no latest year requirement."
                    },
                    "min_property_tax": {
                        "title": "Set Minimum Annual Property Tax",
                        "enum": [
                            "250",
                            "500",
                            "1000",
                            "2000",
                            "3000",
                            "4000",
                            "5000",
                            "6000",
                            "8000",
                            "10000",
                            "20000"
                        ],
                        "type": "string",
                        "description": "Only include listings with annual property tax at or above this amount. Leave empty when there is no minimum annual tax."
                    },
                    "max_property_tax": {
                        "title": "Set Maximum Annual Property Tax",
                        "enum": [
                            "250",
                            "500",
                            "1000",
                            "2000",
                            "3000",
                            "4000",
                            "5000",
                            "6000",
                            "8000",
                            "10000",
                            "20000"
                        ],
                        "type": "string",
                        "description": "Only include listings with annual property tax at or below this amount. Leave empty when there is no maximum annual tax."
                    },
                    "min_maintenance_fee": {
                        "title": "Set Minimum Monthly Maintenance Fee",
                        "enum": [
                            "200",
                            "300",
                            "400",
                            "500",
                            "600",
                            "700",
                            "800",
                            "900",
                            "1000",
                            "1500",
                            "2000"
                        ],
                        "type": "string",
                        "description": "Only include listings with monthly maintenance fees at or above this amount. Leave empty when there is no minimum monthly fee."
                    },
                    "max_maintenance_fee": {
                        "title": "Set Maximum Monthly Maintenance Fee",
                        "enum": [
                            "200",
                            "300",
                            "400",
                            "500",
                            "600",
                            "700",
                            "800",
                            "900",
                            "1000",
                            "1500",
                            "2000"
                        ],
                        "type": "string",
                        "description": "Only include listings with monthly maintenance fees at or below this amount. Leave empty when there is no maximum monthly fee."
                    },
                    "sort_option": {
                        "title": "Sort Listings",
                        "enum": [
                            "date_desc",
                            "date_asc",
                            "price_asc",
                            "price_desc",
                            "open_houses_first",
                            "more_photos_first",
                            "virtual_tour_first"
                        ],
                        "type": "string",
                        "description": "Select the listing order used for the Realtor.ca search results. The default is newest listings first.",
                        "default": "date_desc"
                    },
                    "maximize_coverage": {
                        "title": "Collect all matching listings while respecting maximum limits and filters",
                        "type": "boolean",
                        "description": "Keep this enabled for large searches that may exceed the visible-result limit. Turn it off for faster exploratory runs where the first visible set of matching listings is enough.",
                        "default": true
                    },
                    "limit": {
                        "title": "Set Maximum Results",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Enter the maximum number of listings to save across the whole run. Leave empty to collect as many matching listings as the run can retrieve."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
