# realestate.com.au Scraper — AU Buy + Rent + Sold Listings (`sian.agency/realestate-au-property-scraper`) Actor

API-backed realestate.com.au scraper for AU buy, rent, and sold property listings. Median A$ KPIs, suburb breakdowns, optional full-detail enrichment (description, photos, agency, inspections), HTML report. 6 search modes including polygon.

- **URL**: https://apify.com/sian.agency/realestate-au-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.20 / 1,000 property extracteds

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

## realestate.com.au Scraper 🇦🇺 Buy · Rent · Sold · Auction Data

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![SIÁN-Zoopla UK Property Scraper](https://img.shields.io/badge/SI%C3%81N-Zoopla%20UK%20Property%20Scraper-E6162D)](https://apify.com/sian.agency/zoopla-property-scraper?fpr=sian) [![SIÁN-Zillow Property Scraper](https://img.shields.io/badge/SI%C3%81N-Zillow%20Property%20Scraper-1F4E79)](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian) [![SIÁN-Apartments.com Scraper](https://img.shields.io/badge/SI%C3%81N-Apartments.com%20Scraper-1AE392)](https://apify.com/sian.agency/apartments-com-property-scraper?fpr=sian)

#### 🎉 The only realestate.com.au scraper combining buy + rent + sold archive (incl. auction history) with polygon geofencing and A$ market KPIs in one run
##### Built for Australian property investors, buyer's agents, valuation analysts, PropTech founders, and agency intelligence teams who underwrite deals from data, not gut feel.

---

### 📋 Overview

**Pull every realestate.com.au listing in your target Australian market — for-sale, to-rent, recently-sold (with sold price + sold date + auction history) — and ship ready-to-model A$ KPIs alongside the raw data.** Rank suburbs by median price, comp valuations against sold archive, and export the lot to JSON / CSV / Excel before your next inspection round.

**Why Australian property professionals choose us:**
- ✅ **Buy + Rent + Sold in one actor**: Use `listingType=all` to sweep all three channels per query. Most incumbents ship buy-only.
- 🗺️ **6 search modes incl. polygon geofencing**: `bylocation`, `byzip` (4-digit AU postcode), `bycoordinates` + radius, `bypolygon` (closed lon-lat ring), `byurl`, `bulklocations` (PAID). Only one other AU actor in the top-15 supports polygon.
- 🎯 **A$ market KPIs out of the box**: Median sale / rent / sold (AUD), distribution percentiles (min · median · avg · p90 · max), top-10 suburbs by listing count, state breakdown, property-type tally — computed in-run, no extra calls.
- 💰 **Mid-market wedge pricing**: BRONZE ≈ **$3 / 1,000 listings** ($0.0030 per `property-extracted`), tapering to **$0.0009 at DIAMOND**. We beat the premium tier on price and beat the floor on coverage.
- 💎 **Optional `/details/byid` enrichment**: One toggle bundles full description, every photo, complete general / property feature lists, agency block, advertisers, inspections, and auction time — perfect for listing-detail crawls.
- ✨ **HTML market report** saved to the key-value store on every run — investor / buyer's-agent ready, no extra cost.

---

### ✨ Features

- 🇦🇺 **AU-wide coverage** — every state, every territory, every postcode from Sydney NSW 2000 to Darwin NT 0800
- 🏠 **Sale channel** — live listings for sale, with full pricing range (priceMin / priceMax) and "Contact Agent" displayPrice handling
- 🛌 **Rent channel** — weekly rent (AU convention), furnished / pet-friendly filters, parking-spaces filter
- 🔨 **Sold archive** — recently-sold listings with sold price + sold date + auction history, perfect for comps and valuation research
- 🧭 **Free-text location search** — pass `"Sydney NSW 2000"`, `"Bondi Beach"`, `"Surfers Paradise"` and we resolve it
- 📮 **Postcode search** — 4-digit AU postcode (`2000`, `3000`, `4000`, `6000`, `5000`)
- 📍 **Coordinates + radius** — lat/lon centre + radius in km (0–50)
- 🔷 **Polygon search** — pass a closed lon-lat ring to scrape only inside an irregular boundary (school catchment, beachside strip, harbour view zone)
- 🔗 **URL search** — paste any realestate.com.au search-results URL and we'll parse the filters
- 📋 **Bulk locations (PAID)** — feed an array of suburbs and sweep them in one run
- 🔍 **Rich filters** — property type, price range (AUD), beds, baths, parking, size, construction status, furnished state, keywords, sort order
- 📋 **Optional full-detail enrichment** — toggle `includeDetails` to add description / all photos / full feature lists / agency / inspections / auction time per listing
- 📊 **A$ KPIs in the HTML report** — median by channel, percentile distribution, suburb leaderboard, state breakdown, property-type mix
- 📤 **Clean structured dataset** — 45+ fields, JSON / CSV / Excel export from the Apify dataset UI

---

### 🎬 Quick Start

Pick a search mode, hand us a location (or postcode, coordinates, polygon, URL), pick a listing type (sale / rent / sold / all), and run. Listings stream to the dataset; the HTML report saves to the run's key-value store at `report.html`.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~realestate-au-property-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchMode": "bylocation", "listingType": "sale", "location": "Sydney NSW 2000"}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Pick a search mode

Choose one of: `bylocation` (free-text suburb), `byzip` (4-digit postcode), `bycoordinates` (lat/lon + radius), `bypolygon` (closed lon-lat ring), `byurl` (pasted realestate.com.au URL), or `bulklocations` (array of suburbs, PAID).

#### Step 2: Choose listing type + filters

Pick `sale`, `rent`, `sold`, or `all` (PAID — sweeps all three). Add filters: property type, price range (AUD), beds, baths, parking, keywords. For full listing details (description, photos, agency, inspections, auction time), toggle `includeDetails` (PAID).

#### Step 3: Hit run

The first **25 listings are free** (no credit card). Watch the dataset fill in real time. Download as JSON / CSV / Excel directly from the Apify UI. Grab the HTML report from the key-value store at `report.html`.

**That's it! In under 3 minutes, you'll have:**

- A clean dataset of realestate.com.au listings with 45+ fields
- Median A$ price, suburb breakdown, state breakdown, property-type tally
- An HTML market dashboard you can share with your team or client

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|---|---|---|---|
| `searchMode` | string | Yes | One of: `bylocation`, `byzip`, `bycoordinates`, `bypolygon`, `byurl`, `bulklocations` |
| `listingType` | string | No | `sale` (default), `rent`, `sold`, or `all` (PAID). Ignored when `searchMode=byurl` |
| `location` | string | Conditional | Free-text suburb/town (`bylocation` mode). Default: `Sydney NSW 2000` |
| `locations` | array | Conditional | Array of suburb strings (`bulklocations` mode, PAID) |
| `postalCode` | string | Conditional | 4-digit Australian postcode (`byzip` mode) |
| `latitude` / `longitude` | number | Conditional | Centre point for `bycoordinates` mode |
| `radius` | number | Optional | Search radius in km for `bycoordinates` (0–50, default 5) |
| `polygon` | string | Conditional | Closed `lon lat, lon lat, …` ring (`bypolygon` mode) |
| `realestateUrl` | string | Conditional | Search-results URL (`byurl` mode) |
| `propertyType` | string | Optional | Comma-separated: `house`, `apartment`, `unit`, `townhouse`, `studio`, `villa`, `land`, `acreage`, `rural`, `block_of_units` |
| `priceRange` | string | Optional | `min:N`, `max:N`, or `min:N,max:N` (AUD; weekly for rent, total for sale/sold) |
| `bedsRange` | string | Optional | Bedroom range (`min:0` for studio). e.g. `min:2,max:5` |
| `bathsRange` | string | Optional | Bathroom range. e.g. `min:2` |
| `parkingRange` | string | Optional | Parking-space range. e.g. `min:1` |
| `sizeSqftRange` | string | Optional | Floor / land area in sqft. e.g. `min:500,max:2000` |
| `constructionStatus` | string | Optional | `established`, `builder`, `off_plan`, or empty (any) |
| `furnished` | string | Optional | `furnished`, `unfurnished`, `part_furnished` — rent only |
| `keywords` | string | Optional | Free-text amenity keywords (`pool`, `harbour view`, `air conditioning`) |
| `sortOrder` | string | Optional | `Newest`, `Price_High_to_Low`, `Price_Low_to_High`, `Most_Reduced` |
| `petsAllowed` | boolean | Optional | Rent-only — pet-friendly filter |
| `includeSold` | boolean | Optional | Sale-only — include under-contract / pending listings |
| `maxResults` | integer | Optional | Hard cap per query (default 30, max 500). FREE tier capped at 25 total |
| `includeDetails` | boolean | Optional | **PAID only** — fetch full listing detail (description, all photos, full feature lists, agency, inspections, auction time) |

**Example — sale listings in Sydney CBD by postcode with a price filter:**

```json
{
  "searchMode": "byzip",
  "listingType": "sale",
  "postalCode": "2000",
  "priceRange": "min:800000,max:2500000",
  "bedsRange": "min:2",
  "propertyType": "apartment,unit",
  "sortOrder": "Price_Low_to_High",
  "maxResults": 100
}
```

**Example — bulk-sweep buyer's agent wishlist (PAID):**

```json
{
  "searchMode": "bulklocations",
  "listingType": "sale",
  "locations": ["Bondi NSW 2026", "Coogee NSW 2034", "Bronte NSW 2024"],
  "propertyType": "house",
  "bedsRange": "min:3",
  "includeDetails": true
}
```

**Example — polygon geofence inside Sydney CBD:**

```json
{
  "searchMode": "bypolygon",
  "listingType": "sold",
  "polygon": "151.20 -33.87, 151.22 -33.87, 151.22 -33.89, 151.20 -33.89, 151.20 -33.87"
}
```

***

### 📤 Output

Results are saved to the Apify dataset with **45+ fields per listing**. Every row includes:

| Field | Type | Description |
|---|---|---|
| `propertyId` | string | Internal listing ID (use this for `byurl`/detail lookups) |
| `listingType` | string | `sale`, `rent`, or `sold` |
| `url` | string | Canonical realestate.com.au listing URL |
| `shortUrl` | string | Shortened share URL |
| `thumbnailUrl` | string | Listing thumbnail image |
| `propertyTitle` | string | Listing headline (renamed from `title` to avoid JSON-schema collision) |
| `description` | string | Listing description (truncated in search; full in `detail` when `includeDetails=true`) |
| `address.street` | string | Street line (only present when `showAddress=true`) |
| `address.suburb` | string | Suburb name |
| `address.state` | string | State / territory code (NSW, VIC, QLD, WA, SA, TAS, ACT, NT) |
| `address.postcode` | string | 4-digit AU postcode |
| `address.showAddress` | boolean | Whether the address is publicly displayed |
| `pricing.price` | number | Numeric price (AUD). Weekly rent for rent listings; total for sale/sold |
| `pricing.priceMin` / `priceMax` | number | Range bounds when the listing is priced as a range |
| `pricing.displayPrice` | string | Raw display string (e.g. `"$1,200,000 - $1,350,000"`, `"Contact Agent"`) |
| `pricing.pricePerSqft` | number | Computed when both price and `sizeSqft` are known |
| `pricing.rentFrequency` | string | Rent frequency — `weekly` (AU convention) |
| `specs.beds` / `baths` / `parking` | number | Bedroom / bathroom / parking counts |
| `specs.propertyType` | string | `house`, `apartment`, `unit`, `townhouse`, `studio`, `villa`, `land`, etc. |
| `specs.constructionStatus` | string | `established`, `builder`, `off_plan` |
| `specs.sizeSqft` | number | Floor / land area in sqft |
| `location.latitude` / `longitude` | number | Decimal-degree coordinates |
| `agency.id` / `name` / `phone` / `email` / `website` | string | Listing agency contact block |
| `agency.logo` / `brandColor` | string | Agency branding assets |
| `agency.address` | string | Agency office address |
| `advertisers[]` | array | Listing agents — `{ name, phone }` |
| `media.photoCount` | number | Total photo count |
| `media.mainImage` | string | Hero image URL |
| `media.photos[]` | array | All photo URLs (full list when `includeDetails=true`) |
| `inspections[]` | array | Scheduled inspections — `{ start, end }` ISO timestamps |
| `auctionTime` | string | ISO auction timestamp (`null` if not scheduled) |
| `flags.isBuy` / `isRent` / `isSold` / `isSignature` | boolean | Channel + featured flags |
| `generalFeatures[]` | array | General amenity list (Pool, Air Con, Heating, etc.) |
| `propertyFeatures[]` | array | Property amenity list (Built-in Robes, Ensuite, etc.) |
| `modifiedDate` | string | ISO timestamp of last modification |
| `detail` | object | **PAID only** — full bundle (description, all photos, full feature lists, agency, inspections, auction time) |

**Example row (sale, sold-mode response):**

```json
{
  "propertyId": "146112116",
  "listingType": "sold",
  "url": "https://www.realestate.com.au/property-house-nsw-bondi-146112116",
  "propertyTitle": "Designer family home in Bondi's premier pocket",
  "address": { "street": "12 Example Street", "suburb": "Bondi", "state": "NSW", "postcode": "2026", "showAddress": true },
  "pricing": { "price": 4250000, "displayPrice": "Sold $4,250,000", "rentFrequency": null },
  "specs": { "beds": 4, "baths": 3, "parking": 2, "propertyType": "house", "sizeSqft": 2691 },
  "location": { "latitude": -33.8915, "longitude": 151.2767 },
  "agency": { "id": "RW12345", "name": "Ray White Bondi Beach", "phone": "+61 2 9300 0000", "brandColor": "#FFEC00" },
  "media": { "photoCount": 28, "mainImage": "https://.../main.jpg" },
  "auctionTime": "2026-05-04T11:00:00+10:00",
  "flags": { "isBuy": false, "isRent": false, "isSold": true, "isSignature": false },
  "modifiedDate": "2026-05-04T01:23:45Z"
}
```

**HTML report** — saved to the key-value store as `report.html`. Includes run stats, median A$ price by channel, distribution percentiles (min · median · avg · p90 · max), top-10 suburbs by listing count, state breakdown, property-type tally, per-query totals.

***

### 💼 Use Cases & Examples

#### 1. AU property investor — auto-pulled live + sold comps for a suburb

**For**: investors and buyer's agents who need both live asking prices AND recent sold prices in the same dataset to value a target property.

**Input:** `searchMode=byzip`, `listingType=all`, `postalCode=2026`, `propertyType=house`.
**Output:** every house in postcode 2026 (Bondi) — currently for sale, currently for rent, and recently sold — with median A$ by channel.
**Use:** rank comps by sold price-per-sqm, sanity-check the seller's asking price against the median sold for the same beds/baths cohort, present a defensible offer.

#### 2. Buy-side agent — bulk-sweep a client wishlist across multiple suburbs (PAID)

**For**: buyer's agents managing client briefs across multiple inner-city or coastal suburbs.

**Input:** `searchMode=bulklocations`, `locations=["Bondi NSW 2026", "Coogee NSW 2034", "Bronte NSW 2024"]`, `bedsRange=min:3`, `includeDetails=true`.
**Output:** all 3-bed+ houses across the eastern beaches with full listing detail (description, photos, agency, inspections).
**Use:** generate a single CSV for the client, schedule inspection runs, surface "hidden" listings the client missed on the consumer site.

#### 3. Valuation & comps research — sold-mode archive with auction history

**For**: valuers, mortgage brokers, and PropTech founders building automated valuation models (AVMs).

**Input:** `searchMode=bylocation`, `listingType=sold`, `location=Surfers Paradise QLD 4217`, `propertyType=apartment`, `maxResults=500`.
**Output:** every recently-sold apartment in Surfers Paradise with `pricing.price` = sold price, `modifiedDate` = sold date, `auctionTime` if applicable.
**Use:** train a hedonic regression on beds/baths/sqft → sold price; flag outliers; benchmark against CoreLogic / PriceFinder without paying their per-call fees.

#### 4. Suburb-level market reporting — median price, percentiles, mix

**For**: PropTech newsletters, agency CEOs, council planners, market analysts.

**Input:** `searchMode=bylocation`, `listingType=sale`, `location=Melbourne VIC 3000`, `maxResults=500`.
**Output:** Melbourne CBD sale dataset + HTML report with median, percentile distribution (min · median · avg · p90 · max), property-type tally, top-10 sub-suburbs.
**Use:** monthly market-update content, agency board reports, council infrastructure planning, automated investor newsletters.

#### 5. Real-estate agency competitive intelligence

**For**: independent agencies wanting to track market share against franchise competitors (Ray White, LJ Hooker, Belle, McGrath, etc.).

**Input:** `searchMode=byzip`, `listingType=sale`, `postalCode=4217`, `includeDetails=true`.
**Output:** every listing in the postcode with full `agency.name`, `agency.id`, `advertisers[]`.
**Use:** group by `agency.id` → count listings per branch → rank by listing inventory, track WoW / MoM share, identify recruitment targets.

***

### 🔗 Integration Examples

#### JavaScript / Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('sian.agency/realestate-au-property-scraper').call({
  searchMode: 'byzip',
  listingType: 'sale',
  postalCode: '2000',
  propertyType: 'apartment',
  bedsRange: 'min:2',
  maxResults: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Pulled ${items.length} listings; first row:`, items[0]);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')

run = client.actor('sian.agency/realestate-au-property-scraper').call(run_input={
    'searchMode': 'bylocation',
    'listingType': 'sold',
    'location': 'Bondi NSW 2026',
    'propertyType': 'house',
    'maxResults': 200,
})

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['propertyId'], item['pricing']['price'], item['address']['suburb'])
```

#### cURL — synchronous (results returned inline)

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~realestate-au-property-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchMode": "bypolygon",
    "listingType": "sale",
    "polygon": "151.20 -33.87, 151.22 -33.87, 151.22 -33.89, 151.20 -33.89, 151.20 -33.87",
    "propertyType": "apartment"
  }'
```

#### Automation Workflows (N8N / Zapier / Make / Airtable)

1. **Trigger**: cron schedule (e.g. every Monday 06:00 AEST) or webhook from your CRM
2. **HTTP Request**: `POST /v2/acts/sian.agency~realestate-au-property-scraper/runs?token=YOUR_TOKEN` with your input
3. **Poll or Webhook**: wait for `run.status === "SUCCEEDED"` (or subscribe to the run-finished webhook)
4. **Fetch dataset**: `GET /v2/datasets/{defaultDatasetId}/items?format=json`
5. **Action**: append rows to Airtable / Google Sheets / Notion, fire Slack/email alerts on new sold prices, refresh your PowerBI dashboard

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run — full feature access, every channel, every field, every search mode
- **1 query** per run (single suburb, postcode, or URL)
- No credit card required
- Perfect for testing comps math, validating polygon coordinates, or generating a one-off neighborhood snapshot

#### PAID Tier (Production)

- **Unlimited** listings per run
- **Unlimited** queries / locations
- `listingType=all` (sweeps sale + rent + sold per query)
- `bulklocations` mode (sweep an array of suburbs in one run)
- `includeDetails=true` enrichment unlocks per listing
- Pay-per-event: only successful extractions and successful enrichments are charged

#### Live Per-Event Pricing (USD)

The actor uses **6-tier pay-per-event** pricing. Your effective price depends on your Apify subscription tier. *Display prices on the Apify Store include Apify's standard 20% margin and may appear slightly higher than the dev prices below.*

| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|---|---|---|---|---|---|---|
| `apify-actor-start` (one-time per run) | $0.0500 | $0.0050 | $0.0050 | $0.0050 | $0.0050 | $0.0050 |
| `property-extracted` (per listing) **\[HEADLINE]** | $0.0090 | $0.0030 | $0.0026 | $0.0022 | $0.0015 | $0.0009 |
| `detail-enriched` (per `/details/byid`, opt-in) | $0.0060 | $0.0020 | $0.00175 | $0.0015 | $0.0010 | $0.0006 |

**Headline marketing format** — `property-extracted` at BRONZE = **≈ A$3 / 1,000 listings**, tapering to **≈ A$0.90 / 1,000 listings at DIAMOND**. We sit mid-market: cheaper than the premium feature-rich AU actors (`abotapi` at $0.0035 GOLD) and slightly above the bottom-feeders (`memo23` at $0.0007 GOLD) — the wedge buys you 6 search modes, all three channels, polygon geofencing, A$ KPIs, and the HTML report that none of the cheap actors ship.

**Charge invariants:**

- Charges fire **only on success** — failed extractions and failed enrichments never charge
- Input is validated **before** any charge events fire — you'll never be charged for invalid input
- `detail-enriched` only fires when `includeDetails=true` AND the detail call returns successfully

🔗 [View live pricing on the Apify Store](https://apify.com/sian.agency/realestate-au-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: Is this AU-only?**
A: Yes. realestate.com.au is the dominant Australian property portal (REA Group); the actor only covers Australian listings. For UK property data, use our [Zoopla UK Property Scraper](https://apify.com/sian.agency/zoopla-property-scraper?fpr=sian). For US, use [Zillow Property Scraper](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian) or [Apartments.com Property Scraper](https://apify.com/sian.agency/apartments-com-property-scraper?fpr=sian).

**Q: Which `listingType` options can I use?**
A: `sale` (live for-sale listings, default), `rent` (live to-rent listings — weekly rent), `sold` (recently-sold archive with sold price and sold date), or `all` (PAID — runs every query three times, once per channel). When `searchMode=byurl` the channel is encoded in the URL itself, so `listingType` is ignored.

**Q: How does the sold archive work?**
A: When `listingType=sold`, the actor pulls realestate.com.au's sold-listings index for your area. Each row's `pricing.price` is the final sold price, `modifiedDate` is the sold-date stamp, and `flags.isSold = true`. Coverage typically reaches back ~12–24 months depending on suburb activity.

**Q: Is auction data included?**
A: Yes. Listings that went to auction carry an `auctionTime` ISO timestamp (auction date + time). For sold listings that were auctioned, the `auctionTime` is preserved alongside `pricing.price` (sold price), giving you a full auction-clearance dataset for any postcode or polygon.

**Q: How does polygon mode work?**
A: Pass a closed ring of longitude-latitude pairs as a comma-separated string: `"lon lat, lon lat, lon lat, …"`. The first and last point must match (auto-closed if not). Useful for school catchments, harbourside strips, council-boundary zones, or any irregular area that doesn't fit a postcode. **Note:** AU is in the Southern Hemisphere, so latitudes are negative (`-33.87`).

**Q: What's `includeDetails` for?**
A: When ON, the actor calls `/details/byid` for every listing after the search row, bundling full description, every photo URL, complete general and property feature lists, the agency block, advertisers, inspections, and auction time. Each successful detail call fires one `detail-enriched` charge event. PAID tier only.

**Q: How are the A$ KPIs computed?**
A: Median sale / rent / sold are computed in-run from successfully-extracted `pricing.price` values per channel. Distribution percentiles (min, median, avg, p90, max) are computed across all listings in the run. Suburb tally and state breakdown count `address.suburb` and `address.state` occurrences. All currency values are AUD; rent is always weekly (Australian convention).

**Q: FREE vs PAID limits?**
A: FREE caps each run at 25 listings and 1 query, with `includeDetails` / `listingType=all` / `bulklocations` disabled. PAID is unlimited on listings, queries, and feature flags — pay only per successful extraction (`property-extracted`) and per successful enrichment (`detail-enriched`).

**Q: Can I scrape multiple suburbs / postcodes in one run?**
A: Yes — PAID tier. Use `searchMode=bulklocations` and pass an array of suburb strings in `locations[]`. Each location runs as an independent query; results are merged into a single dataset and a single HTML report.

**Q: What happens on rate-limit?**
A: The actor handles upstream rate-limits transparently with backoff + key fallback (triple-key rotation on 401 / 402 / 403 / 408 / 429 / 5xx responses). You don't need to do anything — failed queries are retried and only successful extractions are charged.

**Q: What output formats are available?**
A: JSON, CSV, Excel, JSONL, XML, RSS, and HTML — export directly from the Apify dataset UI or via `GET /v2/datasets/{datasetId}/items?format=csv`. The HTML market report is saved separately in the run's key-value store at `report.html`.

**Q: Is this legal?**
A: We only extract publicly available data from realestate.com.au — no auth bypass, no private content. You should still comply with realestate.com.au's Terms of Service, the Australian Privacy Act, and the Spam Act when using the data. See the [legal section](#️-is-it-legal-to-scrape-data) below.

***

### 🐞 Troubleshooting

**Empty results — "location not matched"**

- realestate.com.au is strict about location strings. Try `"Sydney NSW 2000"` (suburb + state + postcode) instead of `"Sydney"`. For ambiguous suburb names (Richmond exists in NSW, VIC, QLD, TAS), always include the state.
- Switch to `searchMode=byzip` and pass a 4-digit AU postcode if free-text resolution keeps failing.

**Postcode format error**

- AU postcodes are exactly 4 digits and may have leading zeros (NT starts with `0`, e.g. `0800` for Darwin). Pass them as **strings**, not numbers — `"0800"`, not `800`.

**Polygon mode returns nothing**

- The polygon must be a **closed ring** — first and last point identical. The actor auto-closes it if needed, but malformed coordinate strings will silently drop rows.
- Polygon points are `lon lat` (longitude first, then latitude) — the opposite of the GeoJSON convention many users start from.
- AU latitudes are **negative** (Southern Hemisphere). A polygon with positive latitudes will scrape ocean.

**Large-radius `bycoordinates` queries return unexpected suburbs**

- The `radius` parameter is in **kilometres**, capped at 50. Past ~20 km in metro areas, realestate.com.au pulls from neighbouring postcodes which may not match your buyer's brief — narrow the radius or switch to `bypolygon`.

**`includeDetails` doesn't fire on FREE tier**

- `includeDetails` enrichment is PAID-only by design (it doubles the upstream cost per listing). Switch to PAID or run a smaller smoke test with `includeDetails=false` first.

**Charge events not visible in the run breakdown**

- `apify-actor-start` fires only after input validation passes. If validation fails (missing required field, invalid polygon, etc.), no charge fires and the run exits early — this is intentional, so you're never charged for invalid input.
- `property-extracted` and `detail-enriched` fire only on success. Rows that fail to extract or enrich never charge.

**Rate-limit messages in the logs**

- The actor handles upstream rate-limits internally with backoff + triple-key rotation. The messages are informational — you don't need to take action. If a query ultimately fails after all retries, it's surfaced in the `retry-helper` row in the dataset so you can re-run just the failed queries.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data. They only extract what realestate.com.au has chosen to publish publicly — listing data, agency contact blocks, property descriptions, and photos that any visitor can see by browsing the public site.

That said, your results may contain personal data (agent names, agent phones, agency emails). Personal data is protected by the **Australian Privacy Act 1988** and the **Spam Act 2003**, and in the European Union by the **GDPR**. You should not scrape personal data unless you have a legitimate reason to do so, and you must not use scraped agent contact details for unsolicited commercial messaging without prior consent. If you're unsure whether your reason is legitimate, consult your lawyers.

You are also responsible for complying with **realestate.com.au's Terms of Service** when using the data downstream.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### ⚠️ Trademark Disclaimer

This is an **independent tool** — not affiliated with, endorsed by, or sponsored by REA Group Ltd or realestate.com.au. All trademarks (including REA, realestate.com.au, and any agency brand names appearing in extracted data) are the property of their respective owners. Use of this Actor must comply with realestate.com.au's Terms of Service and applicable Australian law (Privacy Act 1988, Spam Act 2003, Competition and Consumer Act 2010).

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community:**

- For issues or questions, open an issue in the actor's repository on Apify
- Check the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more property + automation tools
- 📧 <apify@sian-agency.online>

***

### ✨ More by SIÁN Agency

- [Zoopla UK Property Scraper](https://apify.com/sian.agency/zoopla-property-scraper?fpr=sian) — UK buy / rent / sold + suburb KPIs
- [Zillow Property Scraper](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian) — US for-sale + Zestimate + 7 search modes
- [Apartments.com Property Scraper](https://apify.com/sian.agency/apartments-com-property-scraper?fpr=sian) — US rental + amenities + lease terms
- [Browse all SIÁN actors →](https://apify.com/sian.agency?fpr=sian)

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** · **[More Tools](https://apify.com/sian.agency?fpr=sian)** · **<apify@sian-agency.online>**

# Actor input Schema

## `searchMode` (type: `string`):

How to specify what to scrape.

• **bylocation** — free-text Australian suburb / town (e.g. "Sydney NSW 2000", "Bondi")
• **byzip** — 4-digit Australian postcode (e.g. 2000, 3000, 4000)
• **bycoordinates** — latitude + longitude + radius (km)
• **bypolygon** — closed polygon ring (lon lat pairs)
• **byurl** — paste a realestate.com.au search-results URL
• **bulklocations** — array of suburbs in one run (PAID)

## `listingType` (type: `string`):

Which side of the Australian market to scrape.

• **sale** — properties for sale (channel=buy)
• **rent** — properties to rent
• **sold** — recently-sold archive (with sold price + sold date)
• **all** — runs each query three times — sale + rent + sold (PAID)

Note: ignored when Search Mode = byurl (the URL itself encodes the channel).

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

Free-text Australian location — suburb, town, region, state, or postcode area.

Examples: `Sydney NSW 2000`, `Bondi Beach`, `Surfers Paradise`, `Melbourne CBD`, `Perth WA`

## `locations` (type: `array`):

Array of Australian suburb / location strings to sweep in one run. PAID tier only.

## `postalCode` (type: `string`):

4-digit Australian postcode.

Examples: `2000` (Sydney CBD), `3000` (Melbourne CBD), `4000` (Brisbane CBD), `6000` (Perth CBD), `5000` (Adelaide CBD)

## `latitude` (type: `number`):

Latitude in decimal degrees. Sydney CBD ≈ `-33.8688`. Australia is in the southern hemisphere — values are negative.

## `longitude` (type: `number`):

Longitude in decimal degrees. Sydney CBD ≈ `151.2093`. Australia uses positive longitudes (east of Greenwich).

## `polygon` (type: `string`):

Closed polygon as `lon lat, lon lat, …` (at least 4 points). First and last point must match (auto-closed if not).

Example (rough Sydney CBD): `151.20 -33.87, 151.22 -33.87, 151.22 -33.89, 151.20 -33.89, 151.20 -33.87`

## `realestateUrl` (type: `string`):

Paste any search-results URL from realestate.com.au.

Examples:

- `https://www.realestate.com.au/buy/in-sydney,+nsw+2000/list-1`
- `https://www.realestate.com.au/rent/property-house-in-melbourne,+vic+3000/list-1`

## `radius` (type: `number`):

Search radius in kilometres. Allowed: 0–50.

## `propertyType` (type: `string`):

Comma-separated property types. Leave empty to include all.

Allowed: `house, apartment, unit, townhouse, studio, villa, land, acreage, rural, block_of_units`

Examples: `apartment`, `house,townhouse`, `land,acreage`

## `priceRange` (type: `string`):

Price range in AUD. Format: `min:N`, `max:N`, or `min:N,max:N`.

For sale/sold: total price. For rent: per-week rent (AU listings are weekly).

Examples: `min:500000,max:1500000`, `max:600`, `min:300000`

## `bedsRange` (type: `string`):

Bedroom range. Studio = `min:0`. Format: `min:N`, `max:N`, or `min:N,max:N`.

Examples: `min:2`, `min:3,max:3`, `min:2,max:5`

## `bathsRange` (type: `string`):

Bathroom range. Format: `min:N`, `max:N`, or `min:N,max:N`.

## `parkingRange` (type: `string`):

Parking-space range (cars / garages / off-street). Format: `min:N`, `max:N`, or `min:N,max:N`.

## `sizeSqftRange` (type: `string`):

Floor or land area in square feet. Format: `min:N`, `max:N`, or `min:N,max:N`.

## `constructionStatus` (type: `string`):

Construction status filter.

• **established** — existing properties
• **builder** — new builds
• **off\_plan** — sold off-plan
• (empty) — any

## `furnished` (type: `string`):

Furnishing state — only used when listingType = rent.

## `keywords` (type: `string`):

Free-text amenity keywords matched against listing descriptions.

Examples: `pool`, `harbour view`, `air conditioning`, `pool tennis`

## `sortOrder` (type: `string`):

How results are sorted. Default: Newest.

## `petsAllowed` (type: `boolean`):

Return only pet-friendly rentals.

## `includeSold` (type: `boolean`):

Also include under-contract / pending listings alongside live ones.

## `maxResults` (type: `integer`):

Hard cap on listings returned per query. Auto-paginates until the cap is reached or the search is fully drained. Default 30 = one API page. FREE tier is always capped at 25 listings per run.

## `includeDetails` (type: `boolean`):

When ON, fetches full listing detail (description, all photos, full general/property features, agency block, inspections, auction time) for each listing — 1 extra API call per listing. Adds a detail-enriched charge per successful enrichment. Disabled on FREE tier.

## Actor input object example

```json
{
  "searchMode": "bylocation",
  "listingType": "sale",
  "location": "Sydney NSW 2000",
  "postalCode": "2000",
  "latitude": -33.8688,
  "longitude": 151.2093,
  "radius": 5,
  "constructionStatus": "",
  "furnished": "",
  "sortOrder": "",
  "petsAllowed": false,
  "includeSold": false,
  "maxResults": 30,
  "includeDetails": false
}
```

# Actor output Schema

## `results` (type: `string`):

Structured realestate.com.au listings (buy / rent / sold) with parsed prices, suburb-level data, agency block, and (optional) full-detail enrichment.

## `htmlReport` (type: `string`):

HTML summary with run stats, market KPIs (median A$, distributions), suburb + property-type breakdowns, and per-query totals.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/realestate-au-property-scraper").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/realestate-au-property-scraper").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 '{}' |
apify call sian.agency/realestate-au-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/realestate-au-property-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "realestate.com.au Scraper — AU Buy + Rent + Sold Listings",
        "description": "API-backed realestate.com.au scraper for AU buy, rent, and sold property listings. Median A$ KPIs, suburb breakdowns, optional full-detail enrichment (description, photos, agency, inspections), HTML report. 6 search modes including polygon.",
        "version": "1.0",
        "x-build-id": "bzf9hf28OUIEZ1QTR"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~realestate-au-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-realestate-au-property-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/sian.agency~realestate-au-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-realestate-au-property-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/sian.agency~realestate-au-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-realestate-au-property-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": {
                    "searchMode": {
                        "title": "🧭 Search Mode",
                        "enum": [
                            "bylocation",
                            "byzip",
                            "bycoordinates",
                            "bypolygon",
                            "byurl",
                            "bulklocations"
                        ],
                        "type": "string",
                        "description": "How to specify what to scrape.\n\n• **bylocation** — free-text Australian suburb / town (e.g. \"Sydney NSW 2000\", \"Bondi\")\n• **byzip** — 4-digit Australian postcode (e.g. 2000, 3000, 4000)\n• **bycoordinates** — latitude + longitude + radius (km)\n• **bypolygon** — closed polygon ring (lon lat pairs)\n• **byurl** — paste a realestate.com.au search-results URL\n• **bulklocations** — array of suburbs in one run (PAID)",
                        "default": "bylocation"
                    },
                    "listingType": {
                        "title": "🏠 Listing Type",
                        "enum": [
                            "sale",
                            "rent",
                            "sold",
                            "all"
                        ],
                        "type": "string",
                        "description": "Which side of the Australian market to scrape.\n\n• **sale** — properties for sale (channel=buy)\n• **rent** — properties to rent\n• **sold** — recently-sold archive (with sold price + sold date)\n• **all** — runs each query three times — sale + rent + sold (PAID)\n\nNote: ignored when Search Mode = byurl (the URL itself encodes the channel).",
                        "default": "sale"
                    },
                    "location": {
                        "title": "📍 Location  (used when Search Mode = bylocation)",
                        "type": "string",
                        "description": "Free-text Australian location — suburb, town, region, state, or postcode area.\n\nExamples: `Sydney NSW 2000`, `Bondi Beach`, `Surfers Paradise`, `Melbourne CBD`, `Perth WA`",
                        "default": "Sydney NSW 2000"
                    },
                    "locations": {
                        "title": "📋 Bulk Locations  (PAID, bulklocations mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of Australian suburb / location strings to sweep in one run. PAID tier only.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "postalCode": {
                        "title": "📮 Postcode  (used when Search Mode = byzip)",
                        "type": "string",
                        "description": "4-digit Australian postcode.\n\nExamples: `2000` (Sydney CBD), `3000` (Melbourne CBD), `4000` (Brisbane CBD), `6000` (Perth CBD), `5000` (Adelaide CBD)"
                    },
                    "latitude": {
                        "title": "🗺 Latitude  (used when Search Mode = bycoordinates)",
                        "type": "number",
                        "description": "Latitude in decimal degrees. Sydney CBD ≈ `-33.8688`. Australia is in the southern hemisphere — values are negative."
                    },
                    "longitude": {
                        "title": "🗺 Longitude  (used when Search Mode = bycoordinates)",
                        "type": "number",
                        "description": "Longitude in decimal degrees. Sydney CBD ≈ `151.2093`. Australia uses positive longitudes (east of Greenwich)."
                    },
                    "polygon": {
                        "title": "🔷 Polygon ring  (used when Search Mode = bypolygon)",
                        "type": "string",
                        "description": "Closed polygon as `lon lat, lon lat, …` (at least 4 points). First and last point must match (auto-closed if not).\n\nExample (rough Sydney CBD): `151.20 -33.87, 151.22 -33.87, 151.22 -33.89, 151.20 -33.89, 151.20 -33.87`"
                    },
                    "realestateUrl": {
                        "title": "🔗 realestate.com.au URL  (used when Search Mode = byurl)",
                        "type": "string",
                        "description": "Paste any search-results URL from realestate.com.au.\n\nExamples:\n- `https://www.realestate.com.au/buy/in-sydney,+nsw+2000/list-1`\n- `https://www.realestate.com.au/rent/property-house-in-melbourne,+vic+3000/list-1`"
                    },
                    "radius": {
                        "title": "📏 Search radius (km)",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "number",
                        "description": "Search radius in kilometres. Allowed: 0–50.",
                        "default": 5
                    },
                    "propertyType": {
                        "title": "🏘 Property type",
                        "type": "string",
                        "description": "Comma-separated property types. Leave empty to include all.\n\nAllowed: `house, apartment, unit, townhouse, studio, villa, land, acreage, rural, block_of_units`\n\nExamples: `apartment`, `house,townhouse`, `land,acreage`"
                    },
                    "priceRange": {
                        "title": "💵 Price range (AUD)",
                        "type": "string",
                        "description": "Price range in AUD. Format: `min:N`, `max:N`, or `min:N,max:N`.\n\nFor sale/sold: total price. For rent: per-week rent (AU listings are weekly).\n\nExamples: `min:500000,max:1500000`, `max:600`, `min:300000`"
                    },
                    "bedsRange": {
                        "title": "🛏 Bedrooms",
                        "type": "string",
                        "description": "Bedroom range. Studio = `min:0`. Format: `min:N`, `max:N`, or `min:N,max:N`.\n\nExamples: `min:2`, `min:3,max:3`, `min:2,max:5`"
                    },
                    "bathsRange": {
                        "title": "🛁 Bathrooms",
                        "type": "string",
                        "description": "Bathroom range. Format: `min:N`, `max:N`, or `min:N,max:N`."
                    },
                    "parkingRange": {
                        "title": "🚗 Parking spaces",
                        "type": "string",
                        "description": "Parking-space range (cars / garages / off-street). Format: `min:N`, `max:N`, or `min:N,max:N`."
                    },
                    "sizeSqftRange": {
                        "title": "📐 Floor / land area (sqft)",
                        "type": "string",
                        "description": "Floor or land area in square feet. Format: `min:N`, `max:N`, or `min:N,max:N`."
                    },
                    "constructionStatus": {
                        "title": "🏗 Construction status",
                        "enum": [
                            "",
                            "established",
                            "builder",
                            "off_plan"
                        ],
                        "type": "string",
                        "description": "Construction status filter.\n\n• **established** — existing properties\n• **builder** — new builds\n• **off_plan** — sold off-plan\n• (empty) — any",
                        "default": ""
                    },
                    "furnished": {
                        "title": "🛋 Furnished state (rent only)",
                        "enum": [
                            "",
                            "furnished",
                            "unfurnished",
                            "part_furnished"
                        ],
                        "type": "string",
                        "description": "Furnishing state — only used when listingType = rent.",
                        "default": ""
                    },
                    "keywords": {
                        "title": "🔑 Free-text keywords",
                        "type": "string",
                        "description": "Free-text amenity keywords matched against listing descriptions.\n\nExamples: `pool`, `harbour view`, `air conditioning`, `pool tennis`"
                    },
                    "sortOrder": {
                        "title": "🔃 Sort order",
                        "enum": [
                            "",
                            "Newest",
                            "Price_High_to_Low",
                            "Price_Low_to_High",
                            "Most_Reduced"
                        ],
                        "type": "string",
                        "description": "How results are sorted. Default: Newest.",
                        "default": ""
                    },
                    "petsAllowed": {
                        "title": "🐾 Pets allowed only (rent)",
                        "type": "boolean",
                        "description": "Return only pet-friendly rentals.",
                        "default": false
                    },
                    "includeSold": {
                        "title": "📌 Include under-contract (sale)",
                        "type": "boolean",
                        "description": "Also include under-contract / pending listings alongside live ones.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "📊 Max results per query",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Hard cap on listings returned per query. Auto-paginates until the cap is reached or the search is fully drained. Default 30 = one API page. FREE tier is always capped at 25 listings per run.",
                        "default": 30
                    },
                    "includeDetails": {
                        "title": "📋 Include full listing detail (PAID)",
                        "type": "boolean",
                        "description": "When ON, fetches full listing detail (description, all photos, full general/property features, agency block, inspections, auction time) for each listing — 1 extra API call per listing. Adds a detail-enriched charge per successful enrichment. Disabled on FREE tier.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
