{
  "openapi": "3.0.1",
  "info": {
    "title": "Realtor.ca - Property Listings, Prices, Agents & Open Houses",
    "description": "From $1/1K. Scrape Realtor.ca property listings with prices, descriptions, images, agent and brokerage details, coordinates, open house times, building features, and more.",
    "version": "1.0",
    "x-build-id": "bfoGcD074SZVtvUgO"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~realtor-ca-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-realtor-ca-scraper",
        "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/abotapi~realtor-ca-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-realtor-ca-scraper",
        "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/abotapi~realtor-ca-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-realtor-ca-scraper",
        "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",
        "properties": {
          "mode": {
            "title": "🎯 Search mode",
            "enum": [
              "location",
              "url"
            ],
            "type": "string",
            "description": "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).",
            "default": "location"
          },
          "locations": {
            "title": "📍 Locations to search",
            "type": "array",
            "description": "Locations to search. Province is optional - leave it blank to use the city's default. Example: Toronto / ON.",
            "items": {
              "type": "object",
              "properties": {
                "city": {
                  "title": "City",
                  "type": "string",
                  "description": "City name, e.g. Toronto, Vancouver, Montreal",
                  "editor": "textfield"
                },
                "province": {
                  "title": "Province",
                  "type": "string",
                  "description": "Canadian province or territory code",
                  "enum": [
                    "AB",
                    "BC",
                    "MB",
                    "NB",
                    "NL",
                    "NS",
                    "NT",
                    "NU",
                    "ON",
                    "PE",
                    "QC",
                    "SK",
                    "YT"
                  ],
                  "editor": "select"
                }
              }
            }
          },
          "listingType": {
            "title": "🏷️ Listing type (buy / rent)",
            "enum": [
              "buy",
              "rent",
              "sold"
            ],
            "type": "string",
            "description": "Type of property listings to scrape.",
            "default": "buy"
          },
          "propertySearchCategory": {
            "title": "🏠 Property category",
            "enum": [
              "residential",
              "commercial",
              "condo",
              "multi-family",
              "vacant-land",
              "recreational",
              "agriculture",
              "parking"
            ],
            "type": "string",
            "description": "Property search category. Determines the type of properties returned.",
            "default": "residential"
          },
          "buildingTypeFilter": {
            "title": "🏢 Building type",
            "enum": [
              "house",
              "row-townhouse",
              "apartment"
            ],
            "type": "string",
            "description": "Filter by specific building type (optional, works within the selected Property Category)"
          },
          "priceMin": {
            "title": "💲 Minimum price",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum property price (CAD)"
          },
          "priceMax": {
            "title": "💲 Maximum price",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum property price (CAD)"
          },
          "bedroomsMin": {
            "title": "🛏️ Minimum bedrooms",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Minimum number of bedrooms"
          },
          "bedroomsMax": {
            "title": "🛏️ Maximum bedrooms",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Maximum number of bedrooms"
          },
          "bathroomsMin": {
            "title": "🛁 Minimum bathrooms",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Minimum number of bathrooms"
          },
          "sortBy": {
            "title": "↕️ Sort order",
            "enum": [
              "6-D",
              "6-A",
              "1-A",
              "1-D"
            ],
            "type": "string",
            "description": "Sort order for search results. Default is 'Newest' (date listed, newest first).",
            "default": "6-D"
          },
          "soldWithinDays": {
            "title": "📅 Sold within last",
            "enum": [
              "7days",
              "14days",
              "30days",
              "90days",
              "6months",
              "1year"
            ],
            "type": "string",
            "description": "Date range for sold listings. Only applies when Listing Type is 'Sold'.",
            "default": "1year"
          },
          "openHouseOnly": {
            "title": "🚪 Open houses only",
            "type": "boolean",
            "description": "Only return listings with upcoming open houses",
            "default": false
          },
          "keywords": {
            "title": "🔎 Keywords",
            "type": "string",
            "description": "Additional search keywords (e.g. 'pool', 'waterfront', 'garage')"
          },
          "urls": {
            "title": "🔗 Search page URLs",
            "type": "array",
            "description": "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/<province>/<city>/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.",
            "default": [
              "https://www.realtor.ca/map#ZoomLevel=11&Center=43.718245%2C-79.376682&LatitudeMax=43.86034&LongitudeMax=-79.12303&LatitudeMin=43.57584&LongitudeMin=-79.63033&view=list&Sort=6-D&PGeoIds=g30_dpz89rm7&GeoName=Toronto%2C%20ON&PropertyTypeGroupID=1&TransactionTypeId=2&PropertySearchTypeId=1&Currency=CAD&IncludeHiddenListings=false",
              "https://www.realtor.ca/bc/vancouver/real-estate"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxListings": {
            "title": "📦 Maximum listings",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after scraping this many listings. Set to 0 for unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "📄 Maximum pages per location",
            "minimum": 0,
            "type": "integer",
            "description": "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).",
            "default": 0
          },
          "simplifyOutput": {
            "title": "🧾 Flat output (simplify)",
            "type": "boolean",
            "description": "When ON, each result is returned as a flat record: address, price, features, coordinates and media become single columns (addressCity, priceValue, featuresBedrooms, ...) and the first agent is lifted to agentName / agentPhone / agentOrganization. Same listings and same billing; only the shape changes. Off by default (nested record).",
            "default": false
          },
          "resumeFromCheckpoint": {
            "title": "⏯️ Resume from checkpoint",
            "type": "boolean",
            "description": "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.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy configuration",
            "type": "object",
            "description": "Residential proxy with country CA (the default) is recommended: this site usually refuses datacenter connections. Residential proxy requires a paid Apify plan.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ],
              "apifyProxyCountry": "CA"
            }
          },
          "resumeFromRunId": {
            "title": "🔁 Resume from run or dataset ID",
            "type": "string",
            "description": "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."
          },
          "incrementalMode": {
            "title": "🔁 Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "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.",
            "default": false
          },
          "stateKey": {
            "title": "🗝️ State key (incremental mode only)",
            "type": "string",
            "description": "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."
          },
          "emitUnchanged": {
            "title": "♻️ Emit unchanged listings (incremental mode only)",
            "type": "boolean",
            "description": "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.",
            "default": false
          },
          "emitExpired": {
            "title": "⌛ Emit expired listings (incremental mode only)",
            "type": "boolean",
            "description": "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.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "🙈 Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "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.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "🔌 Pipe results into your apps (optional)",
            "type": "array",
            "description": "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)."
          },
          "notionParentPageUrl": {
            "title": "📝 Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "🔢 Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}