Domain.com.au - Buy, Rent, Sold & Price History
Pricing
from $1.50 / 1,000 results
Domain.com.au - Buy, Rent, Sold & Price History
Extract enriched Domain.com.au property listings across buy, rent, and sold, with AI-enhanced content and deep structured data including descriptions, features, photos, GPS, agent contacts, suburb insights, school catchments, and complete sold and leased price history timelines.
Pricing
from $1.50 / 1,000 results
Rating
5.0
(1)
Developer
Abot API
Maintained by CommunityActor stats
2
Bookmarked
34
Total users
11
Monthly active users
10 hours ago
Last modified
Categories
Share
Domain.com.au Scraper: Property Listings, History and Insights
Domain.com.au Scraper turns Domain.com.au into a clean property data feed. Search by suburb and filters, or paste Domain search and listing URLs, to pull buy, rent and sold listings with full agent and agency details. Turn on optional add-ons for a property's price history timeline, a valuation and suburb insights, or extra indoor and outdoor listing attributes, then export to JSON, CSV or Excel, or read the results straight through the API.
Why This Scraper?
- Two ways to search. Filter by suburb, listing type and property criteria, or paste Domain search or listing URLs directly.
- Buy, rent and sold listings from one input, each with full agent and agency contact details, not just a listing summary.
- Optional price history timeline for a property's past sold, listed and leased events.
- Optional property insights: a sale and rental valuation estimate, suburb market trends, planning overlays, NBN connection type, school zoning and nearby childcare.
- Optional extended listing attributes: the indoor and outdoor feature split and a few listing-card fields Domain itself doesn't publish.
- Open for inspection and auction filters surface time-sensitive listings coming up in the next 7 days.
- Built for schedules. Incremental mode returns only new and changed listings on recurring runs, and Resume continues a large pull that got interrupted.
Use Cases
- Buyers and renters: track new listings and price changes in a suburb without refreshing Domain by hand.
- Real estate agencies and PropTech: build a lead or comparables database with full agent, agency and pricing detail.
- Investors and valuers: pull price history and valuation estimates to build a suburb level model.
- Market researchers and media: track inventory, days on market and price trends across suburbs over time.
- Portfolio and compliance monitoring: use incremental mode to catch relisted, repriced or delisted properties on a schedule.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | "0000000000" |
url | Domain listing link |
listingType | "buy" (also "rent", "sold") |
displayAddress / addressDisplayType | "1 Example Street, Sample Suburb NSW 2000" / "FULL_ADDRESS" |
suburb / state / postcode | "Sample Suburb" / "NSW" / "2000" |
latitude / longitude | -33.8688 / 151.2093 |
price / priceGuide | "Contact Agent" |
bedrooms / bathrooms / parkingSpaces | 2 / 2 / 1 |
landSize / landSizeUnit | 415 / "m2" |
buildingSize / buildingSizeUnit | 95 / "m2" |
propertyType | "Apartment Unit Flat" |
headline | "Example listing headline." |
description | "Example multi paragraph description." |
structuredFeatures | ["Air Conditioning", "Built-In Wardrobes", "Pool"] |
status / saleMethod / isAuction | "NEW" / "auction" / true |
inspection | schedule with start, end, time and day of week, or null |
firstListedDate | "2026-01-01T00:00:00" |
agencyName / agencyId / agencyProfileUrl / agencyAddress / agencyBrandColour | "Example Real Estate" and its office address |
agents | name, phone, mobile, email, photo, profile URL |
images | the hero image first, then every gallery photo of the listing (photo URLs) |
tags | ["apartment_unit_flat", "new"] |
priceHistory | sold, listed and leased timeline (when Fetch property price history is on) |
valueEstimates / marketInsights / pcaInsights | valuation estimate, suburb trends, planning, NBN and school data (when Property insights is on) |
extendedListing | indoor and outdoor feature split and more (when Extended listing attributes is on) |
When incremental mode is on, every record also carries changeType (NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED), changedFields for an UPDATED record, and firstSeenAt / lastSeenAt timestamps. An EXPIRED record is the last known snapshot of a listing that is no longer found, not a fresh scrape, so its price and enrichment fields reflect whenever it was last seen rather than the current run.
How to Use
- Pick a mode: search (filter by suburb and criteria) or url (paste Domain search or listing URLs).
- For search mode, fill in Locations and the filters you need. For url mode, paste one or more Domain URLs.
- Turn on Fetch property price history, Property insights or Extended listing attributes if you want the enrichment fields, and set Max listings (or Max pages) to control run size.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search a suburb for houses to buy:
{"mode": "search","locations": ["Sydney NSW 2000"],"listingType": "buy","propertyTypes": ["house"],"minBedrooms": 2,"maxListings": 50}
Paste search and listing URLs:
{"mode": "url","urls": ["https://www.domain.com.au/sale/melbourne-vic-3000/","https://www.domain.com.au/1-example-street-sample-suburb-nsw-2000-0000000000"]}
Only listings open for inspection this week:
{"mode": "search","locations": ["Bondi Beach NSW 2026"],"listingType": "rent","inspectionsOnly": true}
Sold listings with price history and property insights:
{"mode": "search","locations": ["Richmond VIC 3121"],"listingType": "sold","fetchPropertyHistory": true,"includePropertyInsights": true,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AU" }}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/domain-com-au-scraper").call(run_input={"mode": "search","locations": ["Sydney NSW 2000"],"listingType": "buy",})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["displayAddress"], listing["price"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/domain-com-au-scraper').call({mode: 'search',locations: ['Sydney NSW 2000'],listingType: 'buy',});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max listings and Max pages cap a run
Max listings is the hard cap on total listings returned (maximum 1,000,000), and 0 means no limit up to the built-in ceiling of 1000 pages per search. Max pages is a coarser cap of roughly 30 listings per page; when both are set, Max listings wins. Filters (bedrooms, bathrooms, price, property type, exclude under offer) are applied after a listing is fetched, so a heavily filtered search can return fewer listings than the cap even though more exist. If Min price or Max price is set, a listing with no parseable price (auction, contact agent, by negotiation) cannot be confirmed in range and is excluded rather than kept.
Resume vs Incremental mode
These are two different features under the same input section:
- Resume (
resumeFromRunId) continues one specific interrupted run. Paste its run or dataset id and this run skips listings already saved there, so it only appends new ones. - Incremental mode (
incrementalMode) is for scheduling the same search again and again, for example daily, and getting only what changed. Each listing is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that scanned the whole search, and only withemitExpiredon).stateKeynames or shares the stored state; leave it blank and the actor derives one from your search scope. Turning both on together is supported once, as a bootstrap: the first run seeds the incremental baseline from the resumed dataset. Those seeded listings come back once more asUPDATEDwith a fullchangedFieldslist on the next run while their snapshot is recorded, and after that you run with incrementalMode alone on a schedule and only real changes come through.
What incremental mode compares. Every listing field is compared (price, price guide, status, sale method, inspection and auction times, bedrooms, bathrooms, parking, land size, description, features, agency, agents, schools and the enrichment blocks), and a change to any of them makes the listing UPDATED with the field named in changedFields. Excluded by default, but still returned on every record: the scrape timestamp, the suburb-wide market insights block, the whole images list (photo URLs on signed image servers rotate between runs, so a changed URL is not a listing change), the listing-card badge text tagText (it ages from New to Updated on Domain's side), and the order of the agents list. Add your own with Ignore fields when detecting changes (ignoreFieldsForChanges, dots for nested fields such as agents.photo); changing that list does not trigger a wave of UPDATED rows. With Max listings set and the default order, Domain does not return the same top listings on every run, so the ones that rotate in show up as NEW; pick a Sort order (for example oldest first) or leave Max listings unlimited for stable monitoring. If an add-on such as price history was unavailable on the first run, the run that first gets it marks those listings UPDATED with priceHistory in changedFields. A run only produces EXPIRED rows when it scanned the whole search: a pasted URL that starts past page 1, a capped run, and inspection or auction time searches never do.
URL mode shapes
Behaviour change: in url mode, leaving urls untouched now scrapes one example of each shape below (previously nothing). Use maxListings to cap the run.
| # | Shape | Example | Support |
|---|---|---|---|
| 1 | Sale search | /sale/melbourne-vic-3000/ | yes |
| 2 | Sale search, paginated | /sale/melbourne-vic-3000/?page=2 | yes, starts at the pasted page (Domain's 20 listings per page) and continues forward; partial scope, no EXPIRED marking |
| 3 | Rent search | /rent/sydney-nsw-2000/ | yes |
| 4 | Rent search, paginated | /rent/melbourne-vic-3000/?page=3 | yes, starts at page 3 (partial scope) |
| 5 | Sold listings | /sold-listings/richmond-vic-3121/ | yes |
| 6 | Sold listings, sorted | /sold-listings/melbourne-vic-3000/?sort=solddate-desc | yes (order set by the Sort input) |
| 7 | Query-form search | /sale/?suburb=bondi-beach-nsw-2026&ptype=house&bedrooms=2-any&sort=price-asc | yes (suburb, property types, bedrooms and sort read from the URL) |
| 8 | Multi-suburb query form | /sale/?suburb=richmond-vic-3121,carlton-vic-3053 | yes, one scope per suburb |
| 9 | Filtered search | /sale/melbourne-vic-3000/?ptype=...&price=500000-1000000&excludeunderoffer=1 | suburb, property types, bedrooms, bathrooms, price band, exclude-under-offer and sort are read from the URL and applied to that URL only (they win over the matching input fields for it); a value that cannot be read is named in a warning |
| 10 | Sorted search | /sale/melbourne-vic-3000/?sort=price-asc | yes, the sort is read from the URL (price-asc, price-desc, dateupdated-*, datelisted-*, suburb-asc) and orders that URL's results only; other URLs in the same run keep their own order |
| 11 | Inspection times path | /sale/sydney-nsw-2000/inspection-times/ | yes |
| 12 | Inspection filter query | /sale/melbourne-vic-3000/?inspectiontimes=1 | yes |
| 13 | Listing detail | /2405-623-collins-street-melbourne-vic-3000-2020262713 | yes |
| 14 | Numeric id only | /2020262713 | yes |
| 15 | New homes landing | /new-homes/ | not supported, logs a warning and skips; if every pasted URL is unsupported the run ends with a message naming them and the supported shapes |
| 16 | Auction results | /auction-results/melbourne/ | not supported, logs a warning and skips (same end-of-run message when it is the only kind of URL given) |
| 17 | New-home project page | /project/6781/623-collins-melbourne-vic/ | not supported (project pages have no per-listing feed), logs a warning and skips |
| 18 | Real-estate agents directory | /real-estate-agents/ | not supported (agent directory, not property listings), logs a warning and skips |
In search mode, locations accept plain suburb names such as Richmond or Bondi Beach. A plain name is looked up in Domain's own suburb search and the top match is used; when several suburbs share the name (Richmond is also in NSW, TAS, SA and QLD) the run uses the top one and logs a warning naming the others, so add the state or postcode (Richmond NSW 2753) to choose. A location that matches no suburb is logged as an error and skipped; if none of your locations match, the run fails instead of returning an empty dataset.
Output views
The dataset has four views in the Console: Overview (address, price, beds, baths, agency), Full Details (every field including enrichment blocks), Changes (incremental) (changeType, changedFields, first and last seen) and Agents (one row per agent) (one row per listing agent with name, phone, mobile, email and agency). The same records are available as JSON, CSV or Excel. A run also writes a short run summary to the OUTPUT record of the key-value store.
Besides the core fields, each record carries listing-card extras such as listingUrl, dateListed, soldPrice, floorPlanImages, videoUrls, agencyUrl, agencyLogoUrl, agentNames, nextInspectionOpen / nextInspectionClose and auctionDate. All additions are extra fields; no existing field was renamed or removed.
Send results into your apps (MCP connectors)
Optionally pipe the scraped listings into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape, the Apify dataset is never changed.
What gets written to the connector: a condensed, human readable summary of each listing, not the full JSON. Each item becomes one entry with a title (the listing's address or headline) and its key fields flattened to plain text: address, price, type, bedrooms and bathrooms, status, agency, agent and a link back to the listing. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you haven't authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where listing pages should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search builds the query from the filters below; url scrapes pasted Domain URLs. |
locations | array | none (prefill: ["Sydney NSW 2000"]) | Suburbs to search, one search per location (search mode only). Accepts "Suburb State Postcode" or a Domain slug. |
sortBy | string | default | Order results by price or date. Search mode only; does not resort a pasted URL's results. |
urls | array | one example of each supported shape | Domain search or listing URLs to scrape (url mode only). |
listingType | string | buy | buy, rent, or sold. Search mode: which listings to search. Any mode: sold also narrows a pasted URL's results to sold or leased listings. |
propertyTypes | array | [] (all types) | Restrict to one or more property types. Applies in search mode and to a pasted URL. |
minBedrooms | integer | none (no minimum) | Applies in search mode and to a pasted URL. |
maxBedrooms | integer | none (no maximum) | Applies in search mode and to a pasted URL. |
minBathrooms | integer | none (no minimum) | Applies in search mode and to a pasted URL. |
minPrice | integer | none (no minimum) | AUD; weekly rent for rent listings. Applies in search mode and to a pasted URL. |
maxPrice | integer | none (no maximum) | AUD; weekly rent for rent listings. Applies in search mode and to a pasted URL. |
excludeUnderOffer | boolean | false | Hide listings marked under offer. |
inspectionsOnly | boolean | false | Search mode only. Only listings with a scheduled inspection in the next 7 days. Paste an inspection times URL in url mode instead. |
auctionsOnly | boolean | false | Search mode only. Only listings going to auction in the next 7 days. Domain has no auction URL to paste, so this is the only way to filter auctions. |
fetchPropertyHistory | boolean | true | Adds the sold, listed and leased price history timeline. Needs Residential proxy, country AU. |
includePropertyInsights | boolean | false | Adds a valuation estimate, suburb market trends, planning overlays, NBN, school zoning and more. Needs Residential proxy, country AU. |
includeExtendedListing | boolean | false | Adds the indoor and outdoor feature split and a few attributes Domain doesn't publish. Needs Residential proxy, country AU. |
maxListings | integer | 20 | Hard cap on total listings across all searches. 0 = no limit. |
maxPages | integer | 0 (no limit) | Coarse cap, about 30 listings per page. maxListings wins when both are set. |
proxy | object | Residential proxy, country AU | Connection settings. Domain.com.au accepts Australian and New Zealand residential connections. |
resumeFromRunId | string | none | Continue one interrupted run: paste its run id or dataset id. |
incrementalMode | boolean | false | Return only new and changed listings on scheduled runs. |
stateKey | string | none (auto derived from your search scope) | Name or share an incremental mode monitoring campaign. |
ignoreFieldsForChanges | string[] | none | Fields (dots for nested, e.g. agents.photo) that never count as a change in incremental mode. They are still returned on every record. |
emitUnchanged | boolean | false | Also return, and bill, listings unchanged since the last run. |
emitExpired | boolean | false | Also return, and bill, listings no longer found, once a run has fully scanned the tracked search. |
mcpConnectors | array | none | Optional: send a summary of each listing to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which listing pages are created. |
maxNotifyListings | integer | 50 | Cap on listings written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": "0000000000","url": "https://www.domain.com.au/1-example-street-sample-suburb-nsw-2000-0000000000","listingType": "buy","displayAddress": "1 Example Street, Sample Suburb NSW 2000","addressDisplayType": "FULL_ADDRESS","street": "1 Example Street","suburb": "Sample Suburb","state": "NSW","postcode": "2000","latitude": -33.8688,"longitude": 151.2093,"price": "Contact Agent","priceGuide": "Contact Agent","bedrooms": 2,"bathrooms": 2,"parkingSpaces": 1,"landSize": 415,"landSizeUnit": "m2","buildingSize": 95,"buildingSizeUnit": "m2","propertyType": "Apartment Unit Flat","headline": "Example listing headline.","description": "Example multi paragraph description.","structuredFeatures": ["Air Conditioning", "Built-In Wardrobes", "Pool", "Security Access"],"saleMethod": null,"isAuction": false,"status": "NEW","inspection": {"byAppointmentOnly": false,"inspections": [{ "start": "2026-01-03T13:45:00", "end": "2026-01-03T14:00:00", "time": "1:45pm", "dayOfWeek": "Saturday" }]},"firstListedDate": "2026-01-01T00:00:00","agencyName": "Example Real Estate","agencyProfileUrl": "https://www.domain.com.au/real-estate-agencies/00000/","agencyId": "QWdlbmN5OjAwMDAw","agencyAddress": {"street": "Example Street","streetNumber": "10","suburb": "Sample Suburb","state": "NSW","postcode": "2000"},"agencyBrandColour": "#000000","agents": [{"id": "QWdlbnQ6MDAwMDAwMA==","name": "Jane Smith","phone": "0400 000 000","mobile": "0400 000 000","email": "jane@example.com.au","photo": "https://example.com/agent-photo.jpg","profileUrl": "https://www.domain.com.au/real-estate-agent/0000000/"}],"images": ["https://example.com/hero-image.jpg"],"tags": ["apartment_unit_flat", "new"],"sourceUrl": "https://www.domain.com.au/1-example-street-sample-suburb-nsw-2000-0000000000","scrapedAt": "2026-01-01T00:00:00.000Z"}
Plan Requirement
Domain.com.au does not serve plain scripted clients, so the actor opens a browser grade session before it reads any page. That session needs a paid Apify plan with proxy access: the default connection is the Apify Residential proxy with country AU (NZ also works). Fetch property price history, Property insights and Extended listing attributes need the Residential connection as well; without it those options are skipped and a warning is logged.
On an Apify free plan the Residential connection is refused. The run then logs "Apify free plans do not include residential proxies" and continues on a backup connection, which may still not be able to read pages. If it cannot load any page the run fails with a clear message instead of finishing empty:
- Connection refused for the account: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required".
- Free plan, backup could not load pages: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Domain pages."
- Any other no-page run: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."
The Pricing tab on the actor page shows the current rates.
FAQ
How much does it cost?
You pay per listing returned, plus a detail-enrichment charge of one unit per listing, billed right after that listing is saved (so a run stopped early has paid only for what it delivered). It applies to a returned listing only when Fetch property price history or Extended listing attributes actually attached data to it; fetchPropertyHistory is on by default, so most default runs include it. Unchanged, suppressed or failed listings are never charged for enrichment. The Pricing tab shows the current rates, and Max listings caps the cost of any run.
Is it legal to scrape Domain.com.au?
This actor collects only publicly available property listing data. You are responsible for how you use it: follow Domain's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution, particularly around agent and agency contact details.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Later runs then return only new, updated and reappeared listings, and unchanged ones are not returned or billed unless you turn on Emit unchanged.
What is the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues one specific run that got interrupted, it is a one-off. Incremental mode is for running the same search again and again on a schedule and getting only the changes each time; it remembers its own state between runs. See "Resume vs Incremental mode" above for the full detail, including how to bootstrap one from the other.
Why did my run fail instead of returning an empty dataset?
If the actor cannot establish a connection to Domain at the start of the run after several automatic retries, the run fails with a clear error (see Plan Requirement for the exact messages) instead of silently returning nothing. Once connected, a listing or results page that still cannot be read after retries is skipped and logged, so a run can finish with fewer listings than exist; check the run log if the count looks low. A resumeFromRunId that doesn't match a run or dataset you can access also fails fast, and turning on Incremental mode together with resumeFromRunId fails if that state key already has tracked listings from an earlier run, since combining them again would be ambiguous; remove one, or set a different State key.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push listing summaries into Notion, Linear or Airtable.
π Want more real estate data?
Pair this actor with these related scrapers from the same team:
| π Real Estate AU Extract detailed Australian real estate property listings with 30+ structured fields... | π Homely.com.au Scrape Homely.com.au properties for sale, rent, and sold, plus agent finder, suburb... |
| π REIWA Scraper Scrape REIWA.com.au across sale, rental, sold, commercial, business and rural properties... | π View.com.au Scraper Scrape View.com.au properties for sale, rent and recently sold across Australia. Search... |
| π€ AU Residential Property From $0.9/1K. Scrape Australian property listings with rich detail-page enrichment. Each... | π Childcare AU Scrape Australiaβs largest childcare directory careforkids.com.au with long day care... |
π Browse all abotapi scrapers
π¬ Support & custom scrapers
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email contact@abotapi.com or message Telegram @abotapi.
- β Enjoying it? A quick review on the actor page helps other users find it.