# Domain.com.au Property Listings & Agent Data Extractor (`dataspryva/domain-com-au-property-listings-and-agent-data`) Actor

Collect Domain.com.au sale, rent and sold property listings by search URL or direct listing URL, with address, price, beds/baths, photos, inspection times, agents and agency details per record.

- **URL**: https://apify.com/dataspryva/domain-com-au-property-listings-and-agent-data.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Domain.com.au Property Listings & Agent Data Extractor

Domain.com.au is one of Australia's two main property portals. This actor turns its public pages into structured JSON: search results for sale, rent and sold listings, individual property detail pages, agent profiles and agency profiles — all without cookies, logins or API keys.

### Modes

| Mode | What it collects | Main fields |
|---|---|---|
| `search` | Builds a Domain search from one or more locations plus filters | Listing cards, with detail enrichment when `scrapeDetails` is on |
| `urls` | Accepts any Domain search URL, listing URL, agent URL or agency URL and routes each one automatically | Mixed record types |
| `agents` | Agent profile pages | Contact details, job title, agency, stats, socials, bio |
| `agencies` | Agency profile pages | Contact details, branding, stats, reviews, team roster, recent listings |

Search mode understands Domain's own filter set: listing type, property types, minimum bedrooms/bathrooms/car spaces, price range, exclude under-offer, surrounding suburbs, sort order and free-text keywords. Every filter is translated into the same query parameters the Domain website uses, so results match what you see on the site.

### What a listing record contains

**From a search page**

- `type` (`domain_listing`), `id`, `url`, `listingType` (`sale`, `rent`, `sold`)
- `title`, `address`, `street`, `suburb`, `state`, `postcode`
- `latitude`, `longitude`
- `price`, `priceLabel`, `pricePeriod` (`week` for rentals), `priceGuide` (`{from, to}` for ranges)
- `propertyType`, `bedrooms`, `bathrooms`, `carspaces`, `landArea`, `landUnit`
- `images`, `inspections`, `auctionDate`
- `agent` (`{name, photo}`), `agencyName`, `agencyColor`, `agencyLogo`, `agentNames`
- `features`, `tag` / `tags`, `projectName`
- `scrapedAt`

**Added when the listing detail page is fetched** (`scrapeDetails: true` or a direct listing URL)

- `headline`, `description`, `descriptionHtml`, `highlights`
- `agents[]` with phone, mobile, email, photo and profile URL, plus `agentPhone`
- `agencyPhone`, `agencyWebsite`, `agencyProfileUrl`, `agencyBanner`, `agencyAddress`
- `floorplans`, `videos`, `virtualTourUrl`, `matterportInterior`, `matterportExterior`
- `landArea`, `buildingArea`, `energyEfficiencyRating`, `propertyReference`
- `listedAt`, `createdOn`, `modifiedOn`, `availableFrom`, `bond`
- `salesMethod`, `listingStatus`, `soldAt`, `soldSaleMethod`, `auctionDate`, `auctionLocation`
- `structuredFeatures[]`, `schoolCatchment[]` (government and independent schools with distance)
- `suburbMedianPrice`, `suburbMedianRent`, `suburbDaysOnMarket`, `suburbAuctionClearance`, `suburbSoldThisYear`, `suburbProfileUrl`

### What an agent record contains

`type` (`domain_agent`), `id`, `url`, `name`, `firstName`, `jobTitle`, `phone`, `mobile`, `photo`, `profileText`, `profileTier`, `agencyId`, `agencyName`, `agencyUrl`, `agencyAddress`, `agencyLogo`, `agencyColor`, social links, `stats` (`forSale`, `forRent`, `sold`, `auctioned`, `leased`, `averageSoldPrice`, `averageDaysOnMarket`), `rating`, `reviewCount`, `activeSuburbs` and `scrapedAt`. Email is included when Domain publishes it on the public page.

### What an agency record contains

`type` (`domain_agency`), `id`, `name`, `url`, `website`, `phone`, `mobile`, `email`, `address`, `logo`, `heroImage`, `color`, `profileTier`, `description`, social links, `stats` (`forSale`, `soldTotal`, `forRent`, `leased`, `sold`, `auctioned`, `averageSoldPrice`, `averageDaysOnMarket`, `totalSaleAmount`), `rating`, `reviewCount`, `reviews[]`, `contacts[]` (the team roster with per-agent stats), `activeSuburbs[]` and `recentListings[]` (up to 24 across sale, rent, sold and leased).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search`, `urls`, `agents` or `agencies` |
| `locations` | array | `["sydney-region-nsw"]` | Suburbs, postcodes, regions or Domain slugs for search mode (`Bondi Beach NSW 2026`, `bondi-beach-nsw-2026`, `sydney-region-nsw`) |
| `listingType` | select | `sale` | `sale`, `rent` or `sold` |
| `propertyTypes` | multi-select | `[]` | House, townhouse, apartment/unit, villa, duplex, terrace, studio, land, acreage, rural, retirement, block of units and new-home types |
| `bedrooms`, `bathrooms`, `carspaces` | select | `any` | Minimum counts (`any`, `1+`, `2+`, …) |
| `minPrice`, `maxPrice` | integer | unset | Whole AUD; weekly rent for rentals |
| `excludeUnderOffer` | boolean | `false` | Hide under-offer / under-contract listings |
| `includeSurroundingSuburbs` | boolean | `true` | Match Domain's default surrounding-suburb expansion |
| `sort` | select | `default` | Featured, price low-to-high or price high-to-low |
| `keywords` | string | unset | Free-text words matched in listing descriptions |
| `includeProjectListings` | boolean | `false` | Include off-the-plan units that Domain shows in project cards |
| `scrapeDetails` | boolean | `false` | Fetch each search result's detail page |
| `searchUrls` | array | `[]` | Any Domain URLs; also the legacy input key. When set, it takes precedence over the search-mode fields so saved tasks keep working |
| `agentUrls`, `agencyUrls` | array | `[]` | Profile URLs for the agent and agency modes |
| `maxItems` | integer | `20` (`3` in prefill) | Records to collect (1–500) |
| `maxPages` | integer | `10` (`1` in prefill) | Search pages per URL (1–50) |
| `proxyConfiguration` | object | off | Optional Apify proxy override; leave off by default |

#### Search for houses in Bondi

```json
{
  "mode": "search",
  "locations": ["bondi-beach-nsw-2026"],
  "listingType": "sale",
  "propertyTypes": ["house"],
  "bedrooms": "3",
  "minPrice": 1000000,
  "maxPrice": 4000000,
  "excludeUnderOffer": true,
  "sort": "price-asc",
  "maxItems": 50
}
```

#### Collect sold comps and their detail pages

```json
{
  "mode": "urls",
  "searchUrls": ["https://www.domain.com.au/sold-listings/bondi-beach-nsw-2026/"],
  "scrapeDetails": true,
  "maxItems": 25
}
```

#### Collect agent and agency profiles

```json
{
  "mode": "agents",
  "agentUrls": ["https://www.domain.com.au/real-estate-agent/david-hua-1895120"]
}
```

```json
{
  "mode": "agencies",
  "agencyUrls": ["https://www.domain.com.au/real-estate-agencies/raywhiteoakleigh-12122/"]
}
```

### Pagination and limits

- Domain returns roughly 20–30 result cards per page and caps a region search at 50 pages (about 1,000 listings). `maxPages` defaults to 10; for deeper coverage split the search into suburbs, property types or price buckets.
- `maxItems` stops the run as soon as enough unique records have been collected. IDs are de-duplicated across pages and URLs.
- Region pages often contain project advertisements plus one or two standard results. Off-the-plan child units are hidden unless `includeProjectListings` is on.

### Anti-bot and proxy

Domain sits behind Akamai bot management. Direct requests, datacenter proxies and residential proxies were all rejected with HTTP 403 during testing, while Apify's UNBLOCKER proxy solves the challenge and returns the normal page. The actor uses the right Apify proxy automatically, so you do not need to configure one. `proxyConfiguration` exists only for users who want to force a specific Apify proxy group; it is off by default.

### FAQ

**Do I need cookies or a login?** No. Every mode reads public pages.

**Can I scrape rentals and sold listings?** Yes — pick `rent` or `sold`, or paste a `/rent/` or `/sold-listings/` URL.

**Why is `price` missing on some listings?** Domain labels many listings `Auction`, `Contact Agent`, `Expressions of Interest` or `Price Withheld`. `priceLabel` keeps that text; `price` is only emitted when a real amount exists.

**Why is an agent email missing?** Domain only publishes emails for some profiles. When it does, the actor decodes and returns it; otherwise the field is omitted.

**What happens when a search has no results?** The run still succeeds and emits one `domain_blocked` record with a `reason` and the URLs you supplied, so downstream pipelines always receive output.

**Is this affiliated with Domain.com.au?** No. This is an independent third-party actor that reads public Domain.com.au pages.

### Limitations

- Domain shows at most 50 result pages per search URL (about 1,000 listings). Use narrower searches (suburb, type, price band, sold date ordering) to go deeper.
- Project advertisements can occupy a large share of a broad region page; keep `includeProjectListings` off for standard listings or search a suburb instead.
- Sold prices are withheld for some listings; the record then keeps the `Price Withheld` label and omits the number.
- Detail-only fields (agents' emails, floor plans, schools, descriptions) require `scrapeDetails` or a direct listing URL and one extra request per listing.

# Actor input Schema

## `mode` (type: `string`):

What to collect. 'search' builds a Domain search from locations + filters. 'urls' accepts any Domain search, listing, agent or agency URL. 'agents' and 'agencies' take profile URLs.

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

Suburbs, postcodes, regions or Domain location slugs. Examples: 'Bondi Beach NSW 2026', 'bondi-beach-nsw-2026', 'sydney-region-nsw', '2000'.

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

Sale, rent or recently sold listings.

## `propertyTypes` (type: `array`):

Optional property-type filter. Leave empty for all types.

## `bedrooms` (type: `string`):

Optional minimum bedroom count.

## `bathrooms` (type: `string`):

Optional minimum bathroom count.

## `carspaces` (type: `string`):

Optional minimum car-space count.

## `minPrice` (type: `integer`):

Optional minimum price in whole Australian dollars. For rentals this is the weekly rent.

## `maxPrice` (type: `integer`):

Optional maximum price in whole Australian dollars. For rentals this is the weekly rent.

## `excludeUnderOffer` (type: `boolean`):

Hide listings marked under offer or under contract.

## `includeSurroundingSuburbs` (type: `boolean`):

When searching a suburb, include nearby suburbs as Domain does by default. Turn off to keep results inside the exact location.

## `sort` (type: `string`):

Result ordering. 'default' keeps Domain's featured order.

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

Optional free-text keywords matched inside listing descriptions (for example 'pool' or 'waterfront').

## `includeProjectListings` (type: `boolean`):

Include individual off-the-plan / new-development units that Domain shows in project cards. Off by default so results contain standard listings.

## `scrapeDetails` (type: `boolean`):

Open each search result's detail page for agent phone/email, description, floor plans, schools, inspection and auction details. Adds one request per listing.

## `searchUrls` (type: `array`):

Domain.com.au search URLs, listing URLs, agent profile URLs or agency profile URLs. Search URLs support all of Domain's own filter query parameters.

## `agentUrls` (type: `array`):

Domain agent profile URLs, for example https://www.domain.com.au/real-estate-agent/david-hua-1895120

## `agencyUrls` (type: `array`):

Domain agency profile URLs, for example https://www.domain.com.au/real-estate-agencies/raywhiteoakleigh-12122/

## `maxItems` (type: `integer`):

Maximum number of records to collect per run.

## `maxPages` (type: `integer`):

Maximum search-result pages to visit per URL. Domain caps region searches at 50 pages (about 1,000 listings), so split by suburb for deeper coverage.

## `proxyConfiguration` (type: `object`):

Optional Apify proxy override. Leave off: the actor automatically uses the right Apify proxy for Domain's anti-bot layer.

## Actor input object example

```json
{
  "mode": "search",
  "locations": [
    "sydney-region-nsw"
  ],
  "listingType": "sale",
  "propertyTypes": [],
  "bedrooms": "any",
  "bathrooms": "any",
  "carspaces": "any",
  "excludeUnderOffer": false,
  "includeSurroundingSuburbs": true,
  "sort": "default",
  "keywords": "",
  "includeProjectListings": false,
  "scrapeDetails": false,
  "searchUrls": [],
  "agentUrls": [],
  "agencyUrls": [],
  "maxItems": 3,
  "maxPages": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing all scraped Domain.com.au property listings, agent profiles and agency profiles.

# 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 = {
    "mode": "search",
    "locations": [
        "sydney-region-nsw"
    ],
    "listingType": "sale",
    "propertyTypes": [],
    "bedrooms": "any",
    "bathrooms": "any",
    "carspaces": "any",
    "excludeUnderOffer": false,
    "includeSurroundingSuburbs": true,
    "sort": "default",
    "keywords": "",
    "includeProjectListings": false,
    "scrapeDetails": false,
    "searchUrls": [],
    "agentUrls": [],
    "agencyUrls": [],
    "maxItems": 3,
    "maxPages": 1,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/domain-com-au-property-listings-and-agent-data").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 = {
    "mode": "search",
    "locations": ["sydney-region-nsw"],
    "listingType": "sale",
    "propertyTypes": [],
    "bedrooms": "any",
    "bathrooms": "any",
    "carspaces": "any",
    "excludeUnderOffer": False,
    "includeSurroundingSuburbs": True,
    "sort": "default",
    "keywords": "",
    "includeProjectListings": False,
    "scrapeDetails": False,
    "searchUrls": [],
    "agentUrls": [],
    "agencyUrls": [],
    "maxItems": 3,
    "maxPages": 1,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/domain-com-au-property-listings-and-agent-data").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "search",
  "locations": [
    "sydney-region-nsw"
  ],
  "listingType": "sale",
  "propertyTypes": [],
  "bedrooms": "any",
  "bathrooms": "any",
  "carspaces": "any",
  "excludeUnderOffer": false,
  "includeSurroundingSuburbs": true,
  "sort": "default",
  "keywords": "",
  "includeProjectListings": false,
  "scrapeDetails": false,
  "searchUrls": [],
  "agentUrls": [],
  "agencyUrls": [],
  "maxItems": 3,
  "maxPages": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dataspryva/domain-com-au-property-listings-and-agent-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/domain-com-au-property-listings-and-agent-data"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/oMfvAaHVj7MAr45xZ/builds/ukAy2O4t3QuBxRWpA/openapi.json
