iProperty MY Scraper - Properties, Prices, Agents & Photos avatar

iProperty MY Scraper - Properties, Prices, Agents & Photos

Pricing

from $1.00 / 1,000 listing results

Go to Apify Store
iProperty MY Scraper - Properties, Prices, Agents & Photos

iProperty MY Scraper - Properties, Prices, Agents & Photos

Scrape property listings from iProperty.com.my for sale or rent: price, PSF, bedrooms, bathrooms, floor area, tenure, property type, full address, agent (name, license, agency, contact numbers) and photo gallery. Search and URL modes, filters, 6 sort orders, and optional detail enrichment.

Pricing

from $1.00 / 1,000 listing results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

4

Total users

1

Monthly active users

3 days ago

Last modified

Share

iProperty.com.my Scraper: Property Listings, Prices, Agents & Photos

iProperty.com.my Scraper turns iProperty.com.my search results into structured property data. Search for sale or rent listings by channel, location, property type, price range and minimum bedrooms, or paste iProperty.com.my search and listing URLs directly, and get a record per property with price, price type, price-per-square-foot, bedrooms, bathrooms, floor area, tenure, the full address with region / district / area, the photo gallery, and the listing agent's name, license, verified status and agency. Two modes (search and URL), 6 sort orders, and location, property-type, price and bedroom filters. An optional detail pass adds the full description, map coordinates, and the agent's phone / WhatsApp contact numbers. Export results to JSON, CSV or Excel, or pull them straight into your app through the API.

Why This Scraper?

  • ~50 fields on a search-mode listing: price type (e.g. Negotiable), price-per-square-foot, tenure, the full photo gallery, the region / district / area breakdown, and the agent / agency profile.
  • Two ways in: build a search from channel + location + filters, or paste iProperty.com.my search and listing URLs directly. Search filters are ignored in URL mode so pasted links are used as-is.
  • 6 sort orders (price, date, built-up size) and location, property-type, price and bedroom filters; the location box accepts plain text ("Petaling Jaya") or the site's own location slug pasted from your address bar.
  • Optional detail enrichment adds the full property description, map coordinates (latitude / longitude), and the listing agent's phone and WhatsApp numbers, billed only on the listings it actually runs for.
  • Built for schedules: Incremental mode returns only new and changed listings on recurring runs, and unchanged rows are never billed unless you ask for them.
  • Export results straight into Notion, Linear, Airtable or Apify via MCP connectors, without touching the dataset.

Use Cases

  • Property portals and lead generation: build a searchable inventory of for-sale or for-rent listings with price, address and agent contact for outreach.
  • Market research and pricing analysis: track price-per-square-foot and asking prices across regions and property types over time.
  • Listing monitoring: watch a specific location or price band on a schedule and get only the new and changed listings, without re-collecting everything.
  • Investment screening: filter by price range, bedrooms and property type to shortlist properties matching an investment thesis.
  • App and CRM feeds: pipe structured listings into your own site, CRM or spreadsheet through the API or MCP connectors.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
listingId900000001
title"Sample Listing, Sample Area"
propertyType"Condominium"
typeText"For Sale"
price{ "value": 650000, "pretty": "RM 650,000", "currency": "MYR", "type": "Negotiable" }
priceType"Negotiable"
psf"RM 480.00 psf"
bedrooms / bathrooms3 / 2
floorArea1100
tenure"Freehold"
location{ "area": "Sample Area", "district": "Sample District", "region": "Selangor" }
fullAddress"Jalan Contoh, Sample Area, Sample District, Selangor"
agent.name / agent.license"Sample Agent" / "REN 00001"
agent.isVerifiedtrue
agency.name"Sample Realty Sdn. Bhd."
agentRating{ "reviewCount": 0, "ratingAverage": 0 }
imageCount1 (matches the length of images)
thumbnail"https://cdn.example.com/listing/900000001/thumb.jpg"
recency"Listed on Jan 05, 2026 (2h ago)"
url"https://www.iproperty.com.my/property/sample-area/sample-project/sale-900000001/"
source"iproperty.com.my"

Search-mode listings (and URL-mode listings pasted as a search URL) also carry propertyTypeGroup, statusCode, externalId, searchUrl, shortAddress, pricePerArea, areaText, badges, postedOn, developer, isOfficialListing, isDeveloperListing, newProject and projectId. iProperty.com.my does not publish per-comment agent reviews on its public pages, so reviews is always returned as null; agentRating (above, commonly 0/0) is the only review signal the site exposes. With Fetch full details on, a record adds description, latitude, longitude, agentContacts (a list of the agent's phone / WhatsApp numbers) and agentPhone whenever the listing page provides them (a failed detail fetch is skipped silently and ships without enrichment), and the images/imageCount gallery is replaced by the fuller detail-page gallery. Pasting a single listing URL (not a search URL) is a narrower shape: it never goes through a search results card, so price, bedrooms, bathrooms, tenure, fullAddress, location, agent and agency are present as keys but always null or empty (images: [], imageCount: 0), alongside the real listingId, id, url, source, listingUrl and scrapedAt, plus the detail-only fields above when Fetch full details is on. Use Search mode, or paste a search URL, to get the full record.

How to Use

  1. Pick a mode: search (build from channel + location + filters) or url (paste iProperty.com.my search or listing URLs).
  2. In search mode, set the channel, an optional location and any filters. In URL mode, paste your links; search filters are ignored.
  3. Turn on Fetch full details if you need the description, coordinates or agent contact numbers, and set Max items to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Search for sale in a location:

{
"mode": "search",
"channel": "sale",
"location": "Petaling Jaya",
"sortBy": "price_asc",
"maxItems": 50
}

Filter rentals by price and bedrooms:

{
"mode": "search",
"channel": "rent",
"priceMin": 1500,
"priceMax": 3500,
"bedrooms": 3,
"propertyType": "condo",
"maxItems": 100
}

Paste a search URL, with full details on:

{
"mode": "url",
"urls": ["https://www.iproperty.com.my/property-for-rent"],
"fetchDetails": true,
"maxItems": 80
}

Daily monitoring with expiry tracking:

{
"mode": "search",
"channel": "sale",
"location": "Mont Kiara",
"incrementalMode": true,
"emitExpired": true,
"maxItems": 0
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/iproperty-com-my-scraper").call(
run_input={"mode": "search", "channel": "sale", "location": "Petaling Jaya", "maxItems": 50}
)
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["title"], listing["pricePretty"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/iproperty-com-my-scraper').call({
mode: 'search', channel: 'sale', location: 'Petaling Jaya', maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume and recurring updates

Two different features, both optional:

  • Resume (resumeFromRunId) continues one specific interrupted crawl: paste a previous run or dataset ID and this run skips every listing already collected there. No state is kept between unrelated runs.
  • Incremental mode (incrementalMode) is for scheduling this same search daily or weekly and getting only what changed. The actor remembers its own baseline for the search (keyed by stateKey, or an automatic key derived from the search/URL and detail settings) and classifies every listing NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED. By default only NEW/UPDATED/REAPPEARED listings ship; turn on emitUnchanged/emitExpired to also get those (both return, and bill, extra rows). EXPIRED rows are only produced once a run has scanned its full tracked search with no cap hit and no Resume. REAPPEARED never happens "by default": a listing can only be marked absent (the one precondition for REAPPEARED) by an earlier run that had emitExpired on and completed that kind of full, uncapped, non-resumed scan. If emitExpired has never been turned on for a state key, REAPPEARED cannot occur for it yet.

Output then carries changeType, changedFields, firstSeenAt and lastSeenAt. Change detection ignores scrapedAt/scraped_at (per-run timestamps) and searchMetadata (search-relative), and it ignores fields that only exist once the optional detail fetch has run (description, latitude, longitude, agentContacts, agentPhone, and the detail-page images/imageCount gallery) whenever the two sides being compared were not fetched at the same depth, so a flaky or toggled detail fetch never manufactures a false UPDATED. recency (e.g. "Listed on Aug 05, 2026 (55s ago)") is normalised, not ignored: the trailing (... ago) relative-age clock is stripped before comparison so it never re-triggers UPDATED on its own, but a genuine change to the listed date still does. Price, bedrooms, bathrooms, floor area, address and every other core field do trigger UPDATED when they change.

Send results into your apps (MCP connectors)

Optionally pipe each run's results into the tools you already use through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed, and a failed export never fails the run.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the mcpConnectors input field.
  3. For Notion, also set notionParentPageUrl: Notion gets one rich page per listing (up to maxNotifyListings, default 50). Linear, Airtable and Apify instead get a single combined note covering up to 25 of the collected listings, sent to whichever writable tool that connector exposes.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch (build from channel + location + filters) or url (use pasted URLs; filters below are ignored).
channelstringsalesale or rent. Search mode only.
locationstringno default (prefill: Kuala Lumpur)Optional state, city, district or neighbourhood name (Kuala Lumpur, Selangor, Petaling Jaya, Mont Kiara). Hyphens work too (petaling-jaya). An iProperty.com.my location slug copied from the address bar (in-kuala-lumpur-58jok) is also accepted verbatim. Empty = whole country.
propertyTypestring`` (all types)Optional property-type filter: bungalow, condo (includes apartments/service residences), semi_detached, terrace, land.
priceMinintegerno defaultMinimum price (MYR).
priceMaxintegerno defaultMaximum price (MYR).
bedroomsintegerno defaultMinimum number of bedrooms.
sortBystringrelevanceOne of 6 sort orders (price, date, built-up size). The site has no bedroom-count sort.
urlsarrayno default (prefill: sample URL)iProperty.com.my search or listing URLs. URL mode only.
fetchDetailsbooleanfalseVisit each listing page for the full description, map coordinates and agent contact numbers. Slower and adds a small per-item charge.
maxItemsinteger20The single cap on the run: stop after collecting this many listings across all searches/URLs. 0 = unlimited.
maxPagesintegerno default (unlimited; defers to Max items)Optional safety bound on result pages per search. Leave empty or 0 for unlimited; the run still stops at Max items.
resumeFromRunIdstringno defaultPaste a previous run or dataset ID to continue a large crawl without returning or charging for listings already collected there. For recurring monitoring of the same search, use Incremental mode instead.
incrementalModebooleanfalseTurn on for daily/recurring monitoring of the same search. The first run returns everything as NEW; later runs normally return only NEW/UPDATED/REAPPEARED.
stateKeystringno defaultOptional. Name a monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Empty = an automatic key derived from the search/URL and detail settings.
emitUnchangedbooleanfalseAlso return (and bill) UNCHANGED listings in incremental mode.
emitExpiredbooleanfalseAlso return (and bill) EXPIRED listings no longer found since the last run. Only produced after a complete, non-resumed, non-capped scan.
proxyobjectResidential (MY)Proxy configuration. Apify Residential recommended.
maxResidentialMBinteger0 (unlimited)Advisory residential traffic budget in MB, logged at startup. Does not currently stop or reroute traffic once a run is underway.
mcpConnectorsarrayno defaultOptional MCP connectors to pipe results into (Notion, Linear, Airtable, Apify).
notionParentPageUrlstringno defaultNotion parent page URL or id for the Notion connector.
maxNotifyListingsinteger50Cap 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 listing.

{
"listingId": 900000001,
"url": "https://www.iproperty.com.my/property/sample-area/sample-project/sale-900000001/",
"title": "Sample Listing, Sample Area",
"propertyType": "Condominium",
"typeText": "For Sale",
"price": { "value": 650000, "pretty": "RM 650,000", "currency": "MYR", "type": "Negotiable" },
"priceValue": 650000,
"pricePretty": "RM 650,000",
"priceType": "Negotiable",
"pricePerArea": "RM 480.00 psf",
"psf": "RM 480.00 psf",
"bedrooms": 3,
"bathrooms": 2,
"floorArea": 1100,
"tenure": "Freehold",
"location": { "area": "Sample Area", "district": "Sample District", "region": "Selangor" },
"fullAddress": "Jalan Contoh, Sample Area, Sample District, Selangor",
"agent": {
"id": 1,
"name": "Sample Agent",
"license": "REN 00001",
"isVerified": true,
"profileUrl": "https://www.iproperty.com.my/property-agent/sample-agent-1/"
},
"agency": { "id": 1, "name": "Sample Realty Sdn. Bhd." },
"agentRating": { "reviewCount": 0, "ratingAverage": 0 },
"images": ["https://cdn.example.com/listing/900000001/photo-1.jpg"],
"imageCount": 1,
"thumbnail": "https://cdn.example.com/listing/900000001/thumb.jpg",
"recency": "Listed on Jan 05, 2026 (2h ago)",
"description": "Full property description (Fetch full details on).",
"latitude": 3.05,
"longitude": 101.7,
"agentContacts": [{ "type": "mobile", "value": "+60123456789" }],
"agentPhone": "+60123456789",
"reviews": null,
"source": "iproperty.com.my",
"scrapedAt": "2026-01-05T00:00:00+00:00"
}

Plan Requirement

Runs on any Apify plan. This site serves best on residential connections, so set the proxy to Apify Residential for reliable results. Datacenter and other non-residential connections are commonly rejected and can return zero items; running on one logs a warning at startup. When the primary connection cannot read a page, the actor tries a backup connection for the rest of that run before giving up.

Reliability

  • Built for resilient, unattended runs: transient errors are retried on a fresh connection automatically.
  • A page that does not exist (HTTP 404) is not retried, and if the run ends with zero items it is reported as PAGE_NOT_FOUND in the status message; that status message only appears on a zero-item run. It means the Location value or a pasted URL points at a page iProperty.com.my does not serve. If a run has several searches or pasted URLs and one of them 404s or is fully blocked, the run stops there and keeps whatever it already collected rather than attempting the rest, with only the run log noting what was skipped.
  • Residential traffic budget: maxResidentialMB is advisory only, logged at run startup. It does not currently stop or reroute traffic once the run is underway. 0 = unlimited.

FAQ

How much does it cost?

You pay per run start, per listing returned, and a smaller amount per listing whose detail page is fetched (only when Fetch full details is on). The Pricing tab shows the current rates for each of these. Use Max items to cap the cost of any run.

This actor collects only publicly available property listing data. You are responsible for how you use it: follow iProperty.com.my's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts (price, size, address) are generally data, but photos and agent profile details may be subject to third-party rights.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and (once a prior complete scan has run with Emit expired on) reappeared listings; unchanged ones are not billed unless you turn on Emit unchanged.

Does this include individual agent review comments?

No. iProperty.com.my does not publish per-comment agent reviews on its public pages, so there is nothing to scrape there. The only review signal the site exposes is an aggregate agentRating (reviewCount / ratingAverage), which is commonly 0.

What does a pasted single listing URL return?

Less than a search-mode record. A pasted listing detail URL never goes through a search results card, so price, bedrooms, bathrooms, tenure, address, agent and agency come back null or empty; you still get the listing id, URL and (with Fetch full details on) the description, coordinates and agent contact numbers. To get the full ~50-field record, use Search mode or paste a search URL instead of an individual listing URL.

Why did my run return fewer listings than expected, or none at all?

A blocked connection does not fail the run; when it returns zero items, the run completes normally with a status message explaining why. When a block or 404 happens partway through a multi-search or multi-URL run after some items were already collected, that stop is visible only in the run log, not in a status message, and this site serves best on a residential proxy. An invalid resumeFromRunId, or turning on Resume for a search that already has saved Incremental mode state, does stop the run outright with a clear error, since continuing would double-count or silently discard that state. Separately, if a run covers several searches or pasted URLs and one of them returns HTTP 404 or is fully blocked, the run stops at that point and keeps whatever it already collected rather than continuing to the rest.

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 real estate data?

Pair this actor with these related scrapers from the same team:

🏠 PropertyGuru MY
From $1/1K. Fast, reliable scraper for propertyguru.com.my. Extract sale and rent...
🏠 PropertyGuru SG Scraper
From $0.80/1K. Scrape PropertyGuru.com.sg sale and rental listings with 30+ structured...
🏠 CommercialGuru SG Property Listings & Agent Contacts Scraper
Scrape commercialguru.com.sg Singapore listings at scale. Extract prices, PSF, floor...
🏷️ Mudah.my Cars, Property, Jobs & Marketplace Scraper
Scrape Mudah.my listings across every category: cars, motorcycles, property, mobiles...
🏠 OnTheMarket Scraper
Scrape onthemarket.com for-sale, to-rent and new-homes listings with 85+ fields: price...
🏠 Zonaprop Argentina
Scrape Zonaprop.com.ar property listings across Argentina. Extract 140+ fields including...

👉 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 abotapi@proton.me or message Telegram @abotapi.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.