{
  "openapi": "3.0.1",
  "info": {
    "title": "Harcourts Property Scraper [Just 💰$1.5] — real estate",
    "description": "💰 $1.5 per 1,000 listings. Scrape harcourts.net — property across Australia New Zealand & Fiji · price with bedrooms & address · GPS coordinates plus open-home inspection times. Incremental mode tracks new and changed listings across scheduled runs.",
    "version": "0.1",
    "x-build-id": "LZeFyf2uCAy7HtakJ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/blackfalcondata~harcourts-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-blackfalcondata-harcourts-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/blackfalcondata~harcourts-scraper/runs": {
      "post": {
        "operationId": "runs-sync-blackfalcondata-harcourts-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/blackfalcondata~harcourts-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-blackfalcondata-harcourts-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": {
          "query": {
            "title": "🔍 Keywords",
            "type": "string",
            "description": "Free text the site matches against listing address and keywords (a street, a suburb, an agent name or a word such as \"renovated\"). Use a JSON array to run several searches. Leave empty to search by Location and filters only."
          },
          "location": {
            "title": "📍 Location",
            "type": "string",
            "description": "Suburb, district or region name (e.g. \"South Perth\", \"Perth - Perth Metro\"). Matched against Harcourts' own location list. Use a JSON array for multi-location."
          },
          "country": {
            "title": "🌍 Country",
            "enum": [
              "AU",
              "NZ",
              "FJ"
            ],
            "type": "string",
            "description": "Which Harcourts market to search.",
            "default": "AU"
          },
          "maxResults": {
            "title": "💯 Max Results",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum total listings to return (0 = unlimited).",
            "default": 100
          },
          "startUrls": {
            "title": "🔗 Start URLs",
            "type": "array",
            "description": "Direct harcourts.net search or listing URLs.",
            "items": {
              "type": "string"
            }
          },
          "listingCategory": {
            "title": "🏷️ Listing Category",
            "enum": [
              "buy",
              "rent",
              "sold",
              "leased"
            ],
            "type": "string",
            "description": "Which set of listings to search.",
            "default": "buy"
          },
          "propertyType": {
            "title": "🏠 Property Type",
            "enum": [
              "",
              "house",
              "unit",
              "apartment",
              "townhouse",
              "villa",
              "land",
              "acreage",
              "duplex",
              "terrace",
              "studio",
              "retirement",
              "block of units",
              "rural",
              "commercial"
            ],
            "type": "string",
            "description": "Restrict to one property type. Rural and Commercial select the matching listing category. For several types, pass a JSON array in the API (any of them matches).",
            "default": ""
          },
          "includeSurroundingSuburbs": {
            "title": "🗺️ Include Surrounding Suburbs",
            "type": "boolean",
            "description": "Also return listings from neighbouring suburbs of the location. Off by default: you get the location you named only.",
            "default": false
          },
          "minPrice": {
            "title": "💰 Min Price",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum price in local currency."
          },
          "maxPrice": {
            "title": "💰 Max Price",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum price in local currency."
          },
          "minBedrooms": {
            "title": "🛏️ Min Bedrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum number of bedrooms."
          },
          "maxBedrooms": {
            "title": "🛏️ Max Bedrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of bedrooms."
          },
          "minBathrooms": {
            "title": "🛁 Min Bathrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum number of bathrooms."
          },
          "maxBathrooms": {
            "title": "🛁 Max Bathrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of bathrooms."
          },
          "minCarspaces": {
            "title": "🚗 Min Car Spaces",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum number of car spaces."
          },
          "minLand": {
            "title": "📐 Min Land Size (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum land size in square metres."
          },
          "maxLand": {
            "title": "📐 Max Land Size (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum land size in square metres."
          },
          "minFloor": {
            "title": "📏 Min Floor Area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum floor area in square metres."
          },
          "maxFloor": {
            "title": "📏 Max Floor Area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum floor area in square metres."
          },
          "propertyFeature": {
            "title": "✨ Property features",
            "type": "string",
            "description": "Comma-separated features a listing must ALL have, e.g. \"Pool, ensuite, airconditioning\". Feature names are the ones harcourts.net uses: Pool, ensuite, builtinrobes, airconditioning, dishwasher, study, garage …"
          },
          "propertyClass": {
            "title": "🏷️ Listing class",
            "enum": [
              "",
              "residential",
              "commercial",
              "rural",
              "business",
              "land"
            ],
            "type": "string",
            "description": "Restrict to one listing class."
          },
          "sortBy": {
            "title": "🔀 Sort order",
            "enum": [
              "",
              "date-desc",
              "date-asc",
              "price-asc",
              "price-desc"
            ],
            "type": "string",
            "description": "Order in which the site returns listings. Matters when Max Results is lower than the number of matches."
          },
          "openHomeDate": {
            "title": "🚪 Open homes on",
            "type": "string",
            "description": "Only listings with an open home (inspection) on this date (YYYY-MM-DD)."
          },
          "auctionDate": {
            "title": "🔨 Auctions on",
            "type": "string",
            "description": "Only listings going to auction on this date (YYYY-MM-DD)."
          },
          "lat": {
            "title": "🌐 Latitude",
            "minimum": -90,
            "maximum": 90,
            "type": "number",
            "description": "Centre point latitude for the distance filter. Set together with Longitude and Search Radius."
          },
          "lon": {
            "title": "🌐 Longitude",
            "minimum": -180,
            "maximum": 180,
            "type": "number",
            "description": "Centre point longitude for the distance filter. Set together with Latitude and Search Radius."
          },
          "radiusKm": {
            "title": "📏 Search Radius (km)",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "Keep only listings within this many kilometres of the Latitude/Longitude point (0 or empty = no distance filter). City and location names are not converted to coordinates, so a point must be given. Listings without a map location are left out while the filter is on. The scan continues until Max Results listings within the radius are found, so combine it with a Location near the point to keep the scan short."
          },
          "includeDetails": {
            "title": "📋 Include Full Details",
            "type": "boolean",
            "description": "Fetch each listing detail page for full description and structured metadata.",
            "default": true
          },
          "includeRelatedEntity": {
            "title": "📧 Include Agent Contact Details",
            "type": "boolean",
            "description": "Fetch each listing agent's profile page to add their email address and bio. Adds one request per distinct agent (results are cached, so agents shared across listings are fetched once).",
            "default": false
          },
          "includeOfficeContacts": {
            "title": "🏢 Include Office Contact Details",
            "type": "boolean",
            "description": "Add the listing office's email address, phone number and street address to every result. Adds one request per run.",
            "default": false
          },
          "descriptionMaxLength": {
            "title": "✂️ Description Max Length",
            "minimum": 0,
            "type": "integer",
            "description": "Truncate description to this many characters. 0 = no truncation.",
            "default": 0
          },
          "compact": {
            "title": "📦 Compact Output",
            "type": "boolean",
            "description": "Output only core fields (for AI-agent/MCP workflows).",
            "default": false
          },
          "descriptionFormat": {
            "title": "Description format",
            "enum": [
              "all",
              "text",
              "html",
              "markdown"
            ],
            "type": "string",
            "description": "Pick a single description representation. `all` keeps every variant; `text` / `html` / `markdown` drop the others.",
            "default": "all"
          },
          "excludeEmptyFields": {
            "title": "Exclude empty fields from output",
            "type": "boolean",
            "description": "Drop null, empty-string, and empty-array fields from each record before push. Smaller payloads for AI agents and dashboards.",
            "default": false
          },
          "incrementalMode": {
            "title": "♻️ Incremental Mode",
            "type": "boolean",
            "description": "Compare against the previous run and label each listing as new, updated or unchanged. State is kept separately for each distinct set of search inputs, so a narrow search never interferes with a broader one.",
            "default": false
          },
          "stateKey": {
            "title": "🔑 State Key",
            "type": "string",
            "description": "Optional. Stable name for the set of listings you are tracking (e.g. \"perth-3bed\"). Leave empty to derive one automatically from your search inputs."
          },
          "emitUnchanged": {
            "title": "♻️ Emit Unchanged Records",
            "type": "boolean",
            "description": "When incremental, also emit records that haven't changed.",
            "default": false
          },
          "emitExpired": {
            "title": "⚰️ Emit Expired Records",
            "type": "boolean",
            "description": "When incremental, also emit records no longer found.",
            "default": false
          },
          "skipReposts": {
            "title": "🚫 Skip Reposts",
            "type": "boolean",
            "description": "When incremental, skip listings whose content matches an expired listing from a prior run (cross-run duplicate detection).",
            "default": false
          },
          "notifyOnlyChanges": {
            "title": "🔄 Notify Only New/Updated",
            "type": "boolean",
            "description": "When Incremental Mode is on, only send notifications for NEW and UPDATED listings. Has no effect outside incremental mode.",
            "default": false
          },
          "notificationLimit": {
            "title": "📊 Max Listings Per Notification",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of listings included in each notification message (1–20).",
            "default": 5
          },
          "telegramToken": {
            "title": "🔑 Telegram Bot Token",
            "type": "string",
            "description": "Telegram bot token (from @BotFather). Required for Telegram notifications."
          },
          "telegramChatId": {
            "title": "💬 Telegram Chat ID",
            "type": "string",
            "description": "Telegram chat or channel ID (e.g. \"-100123456789\"). Required when telegramToken is set."
          },
          "discordWebhookUrl": {
            "title": "🎮 Discord Webhook URL",
            "type": "string",
            "description": "Discord incoming webhook URL. Server Settings → Integrations → Webhooks → New Webhook."
          },
          "slackWebhookUrl": {
            "title": "💼 Slack Webhook URL",
            "type": "string",
            "description": "Slack incoming webhook URL. api.slack.com/messaging/webhooks."
          },
          "whatsappPhoneNumberId": {
            "title": "📞 WhatsApp Phone Number ID",
            "type": "string",
            "description": "Your WhatsApp Business phone-number ID (numeric, from Meta dashboard). Required when whatsappAccessToken is set."
          },
          "whatsappAccessToken": {
            "title": "📱 WhatsApp Access Token",
            "type": "string",
            "description": "WhatsApp Cloud API permanent access token (System User token from Meta Business). Recipient must have messaged the business number within the last 24h (service-conversation window — free since Nov 2024)."
          },
          "whatsappTo": {
            "title": "📲 WhatsApp Recipient",
            "type": "string",
            "description": "Recipient phone in E.164 format without + (e.g. \"436641234567\"). Recipient must have messaged your business number within last 24h."
          },
          "webhookUrl": {
            "title": "🪝 Generic Webhook URL",
            "type": "string",
            "description": "Receives a JSON POST with {metadata, items} after each run. Universal escape hatch for n8n / Make / Zapier / custom backends."
          },
          "webhookHeaders": {
            "title": "📋 Webhook Headers",
            "type": "object",
            "description": "Optional JSON object of custom headers (e.g. {\"Authorization\":\"Bearer ...\"})."
          },
          "appConnector": {
            "title": "Send results to a connected app",
            "type": "string",
            "description": "Optional. Pick a connected app under Settings → API & Integrations to receive your results (including any contact details). Best-effort across MCP connectors as Apify expands its catalog."
          },
          "mcpIssueTeam": {
            "title": "Issue tracker team",
            "type": "string",
            "description": "Only when the connected app is an issue tracker: the team (name or ID) the summary issue is created under, if that app requires one."
          },
          "maxPages": {
            "title": "📄 Max Pages",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Maximum result pages to scrape per search. Raised automatically when Max Results needs more pages. Not used while a Search Radius is active: the scan then continues until Max Results listings within the radius are found or the results run out.",
            "default": 5
          },
          "cityName": {
            "title": "🏙️ City Name",
            "type": "string",
            "description": "City or region to search in (e.g. \"Berlin\", \"Madrid\"). Alias for Location — either field works."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}