Homes.co.nz Scraper - Property Listings, Valuations & Agents
Pricing
from $1.00 / 1,000 results
Homes.co.nz Scraper - Property Listings, Valuations & Agents
Scrape Homes.co.nz listings by location or URL with pagination. Extract property details, valuations, agents, branch information, media and open homes. Search multiple locations per run with filters for status, price, bedrooms and bathrooms.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
14
Total users
4
Monthly active users
5 days ago
Last modified
Categories
Share
Homes.co.nz Scraper: New Zealand Property Listings, Valuations & Agent Details
Homes.co.nz Scraper turns Homes.co.nz into a clean New Zealand property data feed. Search any location or paste Homes detail and map links to collect for sale, for rent, just sold and off market listings with prices, bedrooms and bathrooms, floor and land area, photos and open home times, plus (when enabled) council valuations, title details, and agent and agency contacts. Run it once, or schedule it and get back only what changed, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- Two clean ways to find listings. Search by location name, or paste Homes detail and map links directly. Mix multiple locations or multiple URLs in one run.
- Reads the site's own structured data, not page HTML. Detail and map pages are resolved from the page's embedded application state and the site's gateway API, so extraction stays stable when the page layout changes.
- Dense areas are fully covered. Map searches recursively subdivide the viewport whenever Homes' own map endpoint caps a single call's results, so listings in busy cities are not silently dropped.
- Bedroom and bathroom minimums are double checked. Each returned listing's own room counts are verified again after the fetch, since Homes' own map filter is not reliably narrowing at low minimums.
- Optional deep enrichment. Turn on Fetch Property Cards to add council valuation, title, branch and agent details, or turn it off to cut cost when you only need the core listing fields.
- Built for schedules. Incremental mode tags every listing
NEW,UPDATED,UNCHANGED,REAPPEAREDorEXPIREDagainst your own tracked search, and Resume continues one interrupted large pull without re-paying for listings already saved. - Unreadable inputs fail loudly. If a location, a map page or Homes' map API cannot be read, the run fails instead of quietly returning an empty dataset. Individual listings that cannot be fetched are logged and skipped.
Use Cases
- Property portals and comparison sites: mirror Homes.co.nz for sale, for rent and recently sold listings for a region into your own search experience.
- Valuation and investment research: pull capital value, estimated value and estimated rental ranges alongside each listing to screen for opportunities.
- Market monitoring: track a suburb or city on a schedule with Incremental mode to see new listings, price and status changes, and delistings as they happen.
- Lead generation for agents and buyers' advocates: collect agent and agency contact details attached to active listings in your target areas.
- Market trend analysis: build a historical dataset of prices, floor areas and listing counts for a region over time.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
type | "listing" |
id / listingId | "12345678" |
propertyId | "98765432" |
url / listingDetailUrl | "https://homes.co.nz/address/wellington/te-aro/25-26-marion-street/o02G2" |
title / headline | "25-26 Marion Street, Te Aro, Wellington" |
description | "Stylish two-level apartment close to the CBD..." |
status | 1 (the site's own numeric status code, passed through as-is) |
price / displayPrice | "Auction, 14 Oct 2026" |
priceValue | 950000 |
currency | "NZD" |
bedrooms / bathrooms / carSpaces | 3 / 2 / 1 |
floorArea / landArea | 120 / 450 (square metres) |
address / addressParts | "25-26 Marion Street, Te Aro, Wellington" / { suburb, city, region } |
latitude / longitude | -41.2946 / 174.7766 |
propertyType / listingType | "House" / "residential" |
agentNames / agencyName | ["Jane Smith"] / "Sample Realty" |
openHomes / openHomeCount | open home time slots / 2 |
imageUrls / mediaCount | array of photo URLs / 18 |
valuations.capitalValue | 820000 (when Fetch Property Cards is on) |
estimates.estimatedValue | 905000 (when Fetch Property Cards is on) |
titleRecord.legalDescription | "Lot 4 DP 12345" (when Fetch Property Cards is on) |
publishedAt / updatedAt | ISO timestamps |
changeType / changedFields | "NEW" / [] (Incremental mode only) |
fetchedAt | ISO timestamp this row was scraped |
Every item is the same record shape whether it came from a location search, a map URL or a direct detail URL. Each row also carries branch, agents, propertyDetails, identifiers, sourceEndpoints and seedContext bookkeeping objects (fingerprint and internal ids, the API URLs that produced the row, and the search that seeded it), plus a videoUrls array when a listing includes a virtual tour, and a raw object with the full source payloads when Include Raw Structured Payloads is switched on. With Fetch Property Cards off, the fields that come from the property card are empty: valuations, estimates, titleRecord, propertyDetails, identifiers, agent, branch/branches, agencyName and the suburb, city and region inside addressParts. agentNames and agents can still fill from the listing detail.
How to Use
- Pick a Collection Mode:
search(by one or more location names) orurl(paste Homes detail or map links). - Fill in the fields for that mode, then set the filters under Filters & sort (listing status, minimum bedrooms and bathrooms, price range, sort order). These filters apply to location searches and to map URLs; a single detail URL always returns that one listing.
- Set Max Listings (and optionally Max Pages / Listings Per Page) to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search a location for listings with at least 3 bedrooms:
{"mode": "search","locations": ["Wellington"],"listingStatus": "for_sale","minBedrooms": 3,"maxListings": 50}
Direct Homes links (one detail page, one map area):
{"mode": "url","urls": ["https://homes.co.nz/address/wellington/te-aro/25-26-marion-street/o02G2","https://homes.co.nz/map/wellington?lat=-41.2865&lng=174.7762&zoom=13"],"listingStatus": "for_sale"}
Price-filtered rentals, newest first:
{"mode": "search","locations": ["Auckland Central"],"listingStatus": "for_rent","minPrice": 400,"maxPrice": 800,"sortBy": "published_desc","maxListings": 100}
Recurring monitoring of a suburb, with expired listings flagged:
{"mode": "search","locations": ["Wellington"],"listingStatus": "for_sale","incrementalMode": true,"emitExpired": true,"maxListings": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/homes-co-nz-scraper").call(run_input={"mode": "search", "locations": ["Wellington"], "listingStatus": "for_sale"})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["address"], listing["price"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/homes-co-nz-scraper').call({ mode: 'search', locations: ['Wellington'], listingStatus: 'for_sale' });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 shape a run
Search and map-URL targets resolve their whole candidate set from Homes' map API in one pass, recursively subdividing the map viewport whenever a dense area is capped by the site's own endpoint, then slice that in-memory set into output pages purely for bookkeeping rather than real page by page requests. Leave Max Pages at 0 to walk every page, bounded only by Max Listings and the site's own candidate ceiling. Set Max Pages to a specific number only when you want an explicit page cap below that natural stop.
Resume and recurring updates
- Resume from a prior run (
resumeFromRunId) continues one interrupted crawl: paste its run or dataset ID and the actor skips every listing already saved there, so this run only appends new listings. - Incremental mode (
incrementalMode) is for a search or URL list you run on a schedule. The actor remembers the previous run itself, keyed on a hash of your search scope, with no ID to paste, and classifies each listingNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED.REAPPEAREDonly happens for a listing that a previous complete run already tombstoned asEXPIRED, and which then shows up again. It is not produced by default and needs that priorEXPIREDevent first.EXPIREDis only emitted whenemitExpiredis on and the run completed a full, uncapped pass of every location and URL in scope. A run capped by Max Listings or Max Pages, a map area too dense to fully resolve, or a run that also setsresumeFromRunId, never emitsEXPIREDfor that scope, so a listing that simply was not reached is never mistaken for one that was delisted.
stateKeyoverrides the auto-derived tracked-search identity, which is otherwise a hash of the mode, the locations or URLs, the listing status, bedroom, bathroom and price filters, and Fetch Property Cards (sort order and the output caps are not part of it). CombiningincrementalModewithresumeFromRunIdonly works for the very first incremental run for a given state key; once a real baseline exists, the run fails fast instead of guessing.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results 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 record, not the full JSON. Each item becomes one entry with a title (the listing's headline or address) and its key fields flattened to plain text. 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 have not authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where item 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 (by location) or url (paste Homes links). |
locations | array | none (prefill: ["Wellington", "Auckland Central"]) | Location names to resolve and search. Required when mode is search. |
urls | array | none (prefill: one detail link, one map link) | Homes detail or map URLs. Required when mode is url. |
listingStatus | string | for_sale | for_sale, for_rent, just_sold, or off_market. Applies to location searches and map URLs. |
minBedrooms | integer | none (no minimum) | Only listings with at least this many bedrooms, verified against each returned listing. |
minBathrooms | integer | none (no minimum) | Only listings with at least this many bathrooms, verified against each returned listing. |
minPrice | integer | none | Lower price bound (NZD) sent with the structured query. |
maxPrice | integer | none | Upper price bound (NZD) sent with the structured query. |
sortBy | string | default | default, published_desc, published_asc, price_desc, or price_asc. |
maxListings | integer | 20 | Hard ceiling on listings output across the whole run (0 = no cap). |
maxPages | integer | 0 | Output pages to emit per target (0 = walk every page). |
pageSize | integer | 20 | Listings to emit on each output page. |
fetchPropertyCards | boolean | true | Include extra valuation, title, branch and agent data (one extra request per listing). |
includeRawApiResponses | boolean | false | Include the raw structured API payloads in each item, for debugging. |
resumeFromRunId | string | none | Continue one interrupted run: paste its run or dataset ID. |
incrementalMode | boolean | false | Track this search across scheduled runs and classify each listing's change type. |
stateKey | string | none (auto-derived) | Override the auto-derived tracked-search identity for Incremental mode. |
emitUnchanged | boolean | false | Also return (and bill) listings unchanged since the last incremental run. |
emitExpired | boolean | false | Also return (and bill) listings that dropped out since the last incremental run, only after a complete scan. |
proxyConfiguration | object | { "useApifyProxy": true } | Proxy configuration for Homes requests. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: the page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"type": "listing","id": "12345678","listingId": "12345678","propertyId": "98765432","url": "https://homes.co.nz/address/wellington/te-aro/25-26-marion-street/o02G2","canonicalUrl": "https://homes.co.nz/address/wellington/te-aro/25-26-marion-street/o02G2","title": "25-26 Marion Street, Te Aro, Wellington","description": "Stylish two-level apartment close to the CBD.","status": 1,"price": "Auction, 14 Oct 2026","displayPrice": "Auction, 14 Oct 2026","priceValue": 950000,"currency": "NZD","publishedAt": "2026-08-20T02:00:00.000Z","address": "25-26 Marion Street, Te Aro, Wellington","addressParts": { "full": "25-26 Marion Street, Te Aro, Wellington", "suburb": "Te Aro", "city": "Wellington", "region": "Wellington" },"bedrooms": 3,"bathrooms": 2,"carSpaces": 1,"floorArea": 120,"landArea": 450,"latitude": -41.2946,"longitude": 174.7766,"propertyType": "House","listingType": "residential","agentNames": ["Jane Smith"],"agencyName": "Sample Realty","openHomes": [{ "date": "2026-10-05", "start_time": "13:00", "end_time": "13:30" }],"imageUrls": ["https://images.homes.co.nz/sample1.jpg", "https://images.homes.co.nz/sample2.jpg"],"mediaCount": 18,"valuations": { "capitalValue": 820000, "improvementValue": 340000, "landValue": 480000, "revisionDate": "2024-09-01" },"estimates": { "estimatedValue": 905000, "estimatedValueLow": 860000, "estimatedValueHigh": 950000, "grossYield": 3.8 },"titleRecord": { "legalDescription": "Lot 4 DP 12345", "certificateOfTitle": "WN123/456", "ownershipType": "Freehold" },"sourceEndpoints": { "pageUrl": "https://homes.co.nz/address/wellington/te-aro/25-26-marion-street/o02G2", "listingDetailApi": "https://gateway.homes.co.nz/listing/12345678/detail" },"fetchedAt": "2026-09-28T04:00:00.000Z"}
Plan Requirement
The default proxy setting works out of the box, and failed requests are retried automatically before a run gives up. For large or frequent runs across many locations, a residential proxy group in the Proxy Configuration field gives more headroom.
FAQ
How much does it cost?
You pay per record returned, with property card enrichment adding one extra request per listing when Fetch Property Cards is on. The Pricing tab shows the current rates. Use Max Listings to cap the cost of any run.
Is it legal to scrape Homes.co.nz?
This actor collects only publicly available property listing data. You are responsible for how you use it: follow Homes.co.nz's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Valuation estimates, photos and agent details may be subject to third-party rights.
Can I get only new, changed or removed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then tags every listing NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against your last run for that same search or URL list, and unchanged listings are not returned or billed unless you turn on Emit UNCHANGED.
What is the difference between "Resume from a prior run" and Incremental mode?
They solve different problems. Resume from a prior run continues one interrupted large pull: paste the earlier run or dataset ID and this run skips every listing already saved there. Incremental mode is for a search or URL list you run on a schedule: it remembers the previous run itself, with no ID to paste, and classifies each listing against that stored state. Combining the two only works for the very first incremental run for a given tracked search.
Why did my run fail instead of returning an empty dataset?
The run fails when it cannot read what was asked for: the input is invalid (for example Search mode with no locations), Homes' address search cannot resolve a location, a detail or map URL's page cannot be loaded or read, Homes' map API keeps failing after retries, or a Resume from a prior run ID does not match a run or dataset this Apify account can read (or is combined with Incremental mode after a baseline already exists). Once a listing has been found, a failure fetching its detail or property card after retries does not fail the run: that one listing is skipped and logged, and the run finishes with whatever it could read.
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.
🔗 Want more Homes data?
Pair this actor with these related scrapers from the same team:
| 🧩 Homes.com Scraper Scrape US property records from Homes.com. Pick a city, state or ZIP and a channel (for... | 🚗 Trade Me NZ Scraper Scrape trademe.co.nz across all five sections: Marketplace goods and auctions, Property... |
| 🛒 The Warehouse NZ Scraper Scrape The Warehouse New Zealand search results, category pages, and direct product URLs... | 🏠 OnTheMarket Scraper Scrape onthemarket.com for-sale, to-rent and new-homes listings with 85+ fields: price... |
| 💼 SEEK Company Reviews From $1/1K. Scrape SEEK Australia and New Zealand company profiles and employee reviews... | 🏠 NewHomeSource Scrape new homes, floor plans, builders and communities from NewHomeSource.com. Search by... |
💬 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 abotapi@proton.me or message Telegram @abotapi.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.