REIWA Scraper at a glance
REIWA Scraper is a ready-to-run Apify actor from abotapi for collecting real estate data. Its documented output includes type, title, address, suburb and price, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.50 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Real Estate, Developer Tools, Automation
- Region
- Oceania
- Pricing
- $2.50 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 25 options
Scrape REIWA.com.au across sale, rental, sold, commercial, business and rural properties. Search with filters or URLs and extract structured listings, agents, agencies and market insights across Western Australia.
What REIWA Scraper can do
- Nine REIWA sections, one actor. For sale, for rent, sold, find agents, commercial for sale, commercial for lease, business, rural and insights, all through the same input.
- Two ways in. Build a search from a section, suburbs or regions, price and bedroom filters, or paste REIWA result pages, single listings, agent or agency profiles, and insight articles.
- Agent and agency contact detail. Agent names, profile links, agency names, phone numbers where visible, and profile performance figures such as listings sold and median days on market.
- Optional detail enrichment. Turn on Fetch details to add full descriptions, extra photos, page metadata and richer visible contact fields, billed only for the rows it successfully enriches.
- Full-catalogue pagination. Leave Max pages empty and the run keeps walking result pages until the site's own last-page signal, relying on Max items as the cap.
- Filters that work on both modes. Keywords, property type, price and bedroom filters run as a post-fetch step on search-mode and URL-mode rows alike, though a row with no numeric price or bedroom count is always kept.
Choose what to collect
These inputs let you configure REIWA Scraper - WA Property, Agents & Market Data. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | search builds REIWA result pages from the fields below. url uses the REIWA URLs you paste. |
channelstring | Choose the result type for search mode. URL mode detects the section from each URL. |
locationsarray | Search locations such as perth, perth~region, baldivis, or south-west~region. One search runs per location. Leave empty for all available results where the selected section supports it. The find-agents section uses plain names, so perth~region is searched as perth there. |
sortBystring | Ordering for result pages that support sorting. |
urlsarray | Only used when mode = url. Paste search/list pages (for sale, rent, sold, commercial, business, rural), agent directories, agent and agency profiles, individual listings, insight lists or insight articles. Multiple URLs are supported. Leave the list as is to scrape one example of each page type. |
keywordsstring | Optional text matched against returned titles, addresses, agencies, descriptions, or article summaries. Applies to search and URL modes. |
propertyTypesarray | Optional listing type filters for listing sections. Applies to search and URL modes when supported by the source URL; has no effect when the section is rural. |
Show 18 more inputs
| Input | What it controls |
|---|---|
minPriceinteger | Optional minimum price. For rentals this is weekly rent. |
maxPriceinteger | Optional maximum price. For rentals this is weekly rent. |
minBedroomsinteger | Optional minimum bedrooms. |
fetchDetailsboolean | Adds full descriptions, extra photos, page metadata, and richer contact/profile fields when available. Billed as a detail-enrichment surcharge. |
maxItemsinteger | Hard cap across the whole run. The actor stops once this many rows are saved. |
maxPagesinteger | Optional bound on result pages walked per search/URL. Leave empty to walk every result page. Use Max items as the primary cap. |
resumeFromRunIdstring | Optional: paste a previous run ID (or dataset ID) from this actor. Rows already collected there are skipped, so this run only returns new ones. Leave empty for a normal run. For recurring diff runs (new/changed only on a schedule) you don't need this - turn on Incremental mode below instead. |
incrementalModeboolean | ON: the actor remembers the rows it delivered for this exact search scope (keyed automatically, or use State key below) and on each scheduled run classifies every row as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED - pushing only new and changed rows plus EXPIRED tombstones, and stamping each row with changeType, changedFields, firstSeenAt and lastSeenAt. UPDATED is decided by comparing the whole record: price, price value, bedrooms, bathrooms, parking, agency, agents, phone numbers, description, status and every other returned field. It does NOT compare scrapedAt, the relative date label (dateText), the detail status, the photo list, the result page it was found on (sourceUrl), or any field you list under Ignore fields. Use Change scope to compare only price and status. OFF (default): every run returns the full result set like before. |
stateKeystring | Name for the incremental baseline when Incremental mode is ON. Leave empty to key the baseline on a hash of the search scope automatically (recommended). Use the same key across runs to compare like with like; a different key starts a new baseline. |
emitUnchangedboolean | With Incremental mode ON, also push rows that did not change (stamped changeType=UNCHANGED). Default OFF - unchanged rows are only remembered, not pushed. |
emitExpiredboolean | With Incremental mode ON, push a tombstone row (changeType=EXPIRED, last known field values) for rows from the previous run that this run's search no longer returns - only when the search ran to completion (not capped by Max items or Max pages, not resumed, not started at a later page). Default ON. |
changeScopestring | With Incremental mode ON. 'all' (default): any change in the compared fields makes a row UPDATED. 'priceAndStock': only price, price value, listing status and sold date changes make a row UPDATED; descriptions, agents, photos and the other fields never do. |
compactUpdatesboolean | With Incremental mode ON, UPDATED rows carry only id, title, link, current price fields and priceChanges {field: {old, new}} instead of the full record (no detail payload, so no detail charge rides on a compact row). NEW rows stay full. Default OFF. |
expireAfterMissedScansinteger | With Incremental mode and Push EXPIRED tombstones ON: a row is tombstoned only after it was missing from this many CONSECUTIVE complete scans (default 1 = the first complete scan that misses it). EXPIRED means the search no longer returned the row; it does not prove the property was sold or withdrawn, since a result-page reshuffle and a withdrawal look the same without a detail probe. |
ignoreFieldsForChangesarray | With Incremental mode ON, dataset fields listed here never count as a change (they are excluded from changeType/changedFields while staying in the output). Top-level names (e.g. agentNames) or dotted paths (e.g. profileStats.listings). Built-in defaults already cover the scrape timestamp, the relative date label (dateText), the detail status, the photo list (imageUrls) and the result page link (sourceUrl). |
mcpConnectorsarray | Send the scraped results into apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify Settings, then select it here. The complete record stays in the dataset. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL or id of the Notion page under which item pages are created. Required for Notion export and ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each selected connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
typeType (text)titleTitle (text)addressAddress (text)suburbSuburb (text)pricePrice (text)bedroomsBeds (number)bathroomsBaths (number)parkingSpacesParking (number)propertyTypeProperty (text)agencyNameAgency (text)agentNamesAgents (array)phoneNumbersPhones (array)Show 24 more fields
profileStatsProfile Stats (object)summarySummary (text)descriptionDescription (text)dateTextDate (text)imageUrlsImages (array)urlURL (link)postcodePostcode (text)priceValuePrice Value (number)listingStatusListing Status (text)soldDateSold Date (text)landAreaSqmLand Area Sqm (number)latitudeLatitude (number)longitudeLongitude (number)featuresFeatures (array)detailStatusDetail Status (text)scrapedAtScraped At (text)agencyUrlAgency Url (link)agentUrlsAgent Urls (array)tagsTags (array)idID (text)changeTypeChange (text)changedFieldsChanged fields (array)firstSeenAtFirst seen (text)lastSeenAtLast seen (text)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"id": "5551234",
"type": "for-sale",
"title": "12 Example Street, Sampleford",
"address": "12 Example Street, Sampleford",
"suburb": "Sampleford",
"url": "https://reiwa.com.au/12-example-street-sampleford-5551234/",
"sourceUrl": "https://reiwa.com.au/for-sale/perth~region/",
"price": "$650,000",
"priceValue": 650000,
"bedrooms": 4,
"bathrooms": 2,
"parkingSpaces": 2,
"propertyType": "House",
"agencyName": "Sample Realty Group",
"agencyUrl": "https://reiwa.com.au/real-estate-agency/sample-realty-group/",
"agentNames": [
"Jordan Sample"
],
"agentUrls": [
"https://reiwa.com.au/real-estate-agent/jordan-sample/"
],
"phoneNumbers": [
"0491570156"
],
"dateText": "Added 4 days ago",
"imageUrls": [
"https://imagecdn.reiwa.com.au/listing/34/5551234-01.jpg"
],
"description": "Sample listing description text goes here.",
"pageTitle": "12 Example Street, Sampleford - For Sale | REIWA",
"detailStatus": "ok",
"scrapedAt": "2026-01-01T00:00:00.000Z"
}Ways to use this data
- Buyers and renters: track new listings in chosen suburbs, filtered by price range and bedroom count.
- Lead generation: build contact lists of agents and agencies active in a region, with phone numbers and profile links.
- Market research: pair sold listings with insight articles to study price trends across WA.
- Portfolio tracking: monitor commercial, business and rural listings for acquisition or leasing opportunities.
- CRM and workflow automation: pipe new rows into Notion, Linear or Airtable through MCP connectors as they're collected.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does REIWA Scraper return?
The documented output for REIWA Scraper includes type, title, address, suburb, price, beds, baths and parking. Availability of each field depends on the source page and the selected mode.
How much does REIWA Scraper cost?
It costs $2.50 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new listings on a recurring schedule?
Yes. Turn on Incremental mode: the first run returns everything as NEW, later runs on the same scope return only NEW, UPDATED, REAPPEARED and EXPIRED rows (see the incremental section above). Resume (resumeFromRunId) is different: it skips rows collected in one earlier run and is meant for continuing an interrupted run.
Why did my run fail instead of returning an empty dataset?
An empty dataset can mean the search or filters matched nothing on the find-agents or insights sections, or, for a listing search, that the section returned a single page-level row rather than any listings at all. A page that does not exist (a mistyped pasted URL included) is skipped with a "Page not found" warning, and a search whose page can't be loaded is skipped with a "Could not load" warning, so the other searches in the same run still finish. A search whose first page returns no results logs a warning, and a run that saves nothing says so in the log. The run fails only when no page could be loaded at all ("Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."). Rows already saved before a failure stay in the dataset and are billed for. Check the run log, then run it again in a few minutes.
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 results into Notion, Linear or Airtable.
