# Realestate.com.kh Scraper | Cambodia Property Listings (`haketa/realestate-com-kh-scraper`) Actor

Scrape Cambodia's #1 property portal realestate.com.kh. Houses, condos, land & villas in Phnom Penh & Siem Reap. USD prices, Hard/Strata Title, Borey filter & foreign-eligible listings.

- **URL**: https://apify.com/haketa/realestate-com-kh-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Real estate, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

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

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Realestate.com.kh Scraper — Cambodia Property Listings, Phnom Penh Condos, Siem Reap Villas & Sihanoukville Investor Data

> **The most complete Realestate.com.kh data extraction tool on Apify.** Pull live Cambodia property listings — houses, condos, villas, land, shophouses, commercial and Borey gated-community projects — directly from Cambodia's #1 property portal. USD prices, Hard / Soft / Strata Title status, commune-level location, agency contacts, coordinates and full image galleries — structured and ready for foreign-investor research, expat relocation, condo pre-sale comps, hotel acquisition due diligence and Cambodia real estate market intelligence.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/realestate-com-kh-scraper)
[![Live Data](https://img.shields.io/badge/Data-Live%20at%20Run%20Time-orange)]()
[![Engine](https://img.shields.io/badge/Engine-HTTP%20%2B%20Cheerio-green)]()
[![No Auth](https://img.shields.io/badge/Authentication-None%20Required-success)]()
[![Coverage](https://img.shields.io/badge/Coverage-All%20Cambodia-purple)]()
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay%20Per%20Event-yellow)]()
[![Region](https://img.shields.io/badge/Region-Cambodia-red)]()
[![Currency](https://img.shields.io/badge/Currency-USD-informational)]()

---

### What This Actor Does

The **Realestate.com.kh Scraper** is a production-ready Apify Actor that extracts structured property listings from **[realestate.com.kh](https://www.realestate.com.kh/)** — Cambodia's largest and most trusted English-language property portal, owned by the Digital Classifieds Group and used by virtually every international real estate agency operating in the Kingdom.

Cambodia is one of Southeast Asia's most foreign-friendly property markets — listings are priced in **US dollars**, condominium ownership is open to foreigners (above ground floor), Phnom Penh's BKK1 district hosts dense expat condo developments, Sihanoukville is reshaping itself around Chinese investor capital, and Siem Reap remains a tourism-driven villa and boutique hotel market. Realestate.com.kh aggregates listings across all of these markets in one searchable inventory, and this actor turns that inventory into a clean JSON dataset.

In a single run the actor returns structured records covering:

- **Houses & Link Houses** — single-family and terraced housing across Phnom Penh, Siem Reap, Battambang and provincial markets
- **Condominiums** — the booming Phnom Penh condo segment (BKK1, Tonle Bassac, Toul Kork, Daun Penh, Chamkarmon) and Sihanoukville beachfront towers
- **Villas & Twin Villas** — high-end residential product in Chamkarmon, Toul Kork and Borey-style gated estates
- **Land** — Hard Title and Soft Title plots, vital for developers, hotel acquisitions and agricultural buyers
- **Shophouses** — the iconic Cambodian commercial-residential hybrid, dense in Phnom Penh's commercial corridors
- **Commercial** — office, retail and mixed-use rental and sale stock
- **Borey projects** — gated, master-planned community housing (a uniquely Cambodian asset class)
- **New Developments** — pre-sale and off-plan condo, villa and Borey projects with developer-level data

Every record carries the listing's **USD price**, **bedrooms / bathrooms**, **floor and land area in square metres**, **commune / district / province** location, **listing URL**, and (when detail-page scraping is enabled) **Hard / Soft / Strata Title status**, **agency name**, **contact phone**, **map coordinates**, **full image gallery**, **features list** and the **description**. That makes it the **fastest way to build or refresh a Cambodia real estate dataset** for foreign-investor due diligence, expat relocation tooling, condo comps, hotel and resort M&A research, or Khmer-market analytics.

---

### Why scrape Realestate.com.kh yourself when this exists?

Realestate.com.kh is a modern Next.js application with server-side rendering, JSON-blob hydration via `__NEXT_DATA__`, lazy-loaded image galleries, and a non-trivial URL taxonomy that mixes commune slugs, bed/bath counts and property-type tokens into a single path. Most teams who try a DIY scrape hit the same wall:

- The site renders cards in **Next.js SSR** — naive BeautifulSoup/requests scripts get partial data because key fields live in the `__NEXT_DATA__` JSON blob, not in the visible HTML
- **Detail pages bury** the title type (Hard / Soft / Strata / LMAP), agency, original ID, listed-on date and coordinates in a deeply nested `pageProps.cacheData.listing.data` structure that changes shape across listing types
- The URL pattern `/buy/{commune}/{N}-bed-{M}-bath-{type}-{id}/` looks predictable but **breaks for studios, land, and commercial listings** which have no bed/bath segment
- **Relative dates** (`"3 weeks ago"`, `"6 months ago"`) need to be parsed and normalised against `now()` to be useful in a database
- Cambodian location data has three levels — **commune (sangkat) / district (khan) / province** — and the address string concatenates them inconsistently
- USD price strings include `$`, `,`, `+` ribbons and discount badges that have to be stripped before the number is usable
- Pagination is straightforward `?page=N` until you hit the dynamic infinite-scroll boundary and your simple loop never stops
- **Borey project names** (gated community brand names like "Borey Peng Huoth", "Borey Vimean Phnom Penh") appear only on detail pages, not in the listing cards
- **Image URLs** sit behind a CDN (`images.realestate.com.kh`) with multiple size variants — picking the right one needs domain knowledge
- Pre-sale condo and Borey "new development" listings have a different schema again — project-level not unit-level — and most DIY scripts silently drop them
- Rate-limiting is gentle but **does** kick in over a few hundred sequential requests without backoff
- Maintaining all of this for the next six months while the Next.js bundle hash changes weekly is a part-time job nobody on your team signed up for

This actor solves every one of those problems: it tries `__NEXT_DATA__` first, falls back to DOM parsing, normalises USD prices, parses relative dates, splits commune / district / province, dedupes by listing ID, follows pagination cleanly, and yields **uniform records ready for Postgres, BigQuery, Sheets, Power BI or your CRM** — no Cheerio glue code, no Next.js reverse engineering, no proxy plumbing.

---

### Quick Start

#### One-Click Run

1. Click **"Try for free"** on the [Apify Store page](https://apify.com/haketa/realestate-com-kh-scraper)
2. Pick a `listingType` (`buy` / `rent` / `new-developments` / `all`), a `propertyType` (e.g. `condo`, `villa`, `land`, `borey`) and add city slugs to `cities` (e.g. `["phnom-penh", "siem-reap"]`)
3. Hit **Start** — the actor scrapes the search result pages, paginates automatically, and writes structured listings to your dataset
4. Download as **JSON, CSV, Excel, HTML, XML, RSS or JSON Lines** straight from the Apify dataset view, or pull it via the dataset API into your data pipeline

#### API Run (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/realestate-com-kh-scraper").call(run_input={
    "listingType": "buy",
    "propertyType": "condo",
    "cities": ["bkk-1", "tonle-bassac", "toul-kork"],
    "scrapeDetails": True,
    "maxRecords": 500,
    "requestDelay": 1500,
    "proxyConfiguration": {"useApifyProxy": True}
})

for record in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(
        record["propertyId"],
        record["title"],
        f"${record['price']:,}" if record.get("price") else "POA",
        f"{record.get('bedrooms') or '-'}br",
        record.get("commune"),
        record.get("titleType") or "—",
    )
````

#### API Run (Node.js / TypeScript)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/realestate-com-kh-scraper').call({
    listingType: 'buy',
    propertyType: 'villa',
    cities: ['siem-reap', 'sihanoukville'],
    scrapeDetails: true,
    maxRecords: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Pulled ${items.length} villas across Siem Reap and Sihanoukville`);

for (const v of items.slice(0, 5)) {
    console.log(`${v.title} — $${v.price?.toLocaleString() ?? 'POA'} — ${v.commune}, ${v.province}`);
}
```

#### API Run (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~realestate-com-kh-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "listingType": "rent",
    "propertyType": "apartment",
    "cities": ["bkk-1", "chamkarmon", "daun-penh"],
    "maxRecords": 300,
    "scrapeDetails": false
  }'
```

#### Direct URL Mode (skip filters)

If you already have a curated set of Realestate.com.kh search URLs from your own market research, drop them straight into `startUrls`:

```json
{
  "startUrls": [
    "https://www.realestate.com.kh/buy/phnom-penh/condo/",
    "https://www.realestate.com.kh/buy/sihanoukville/",
    "https://www.realestate.com.kh/rent/siem-reap/villa/",
    "https://www.realestate.com.kh/new-developments/phnom-penh/"
  ],
  "scrapeDetails": true,
  "maxRecords": 0
}
```

When `startUrls` is set, the `listingType`, `propertyType` and `cities` filters are ignored — your URLs take precedence.

***

### How It Works

The actor combines **`got-scraping` (HTTP with realistic browser fingerprinting) + Cheerio (HTML parsing) + a JSON-blob extractor that hooks into Next.js's `__NEXT_DATA__` hydration script**. Because Realestate.com.kh is fully server-rendered, no headless browser is required — which keeps runs fast, cheap, and reliable.

#### Source endpoints

| Endpoint pattern | Example | What it returns |
|---|---|---|
| `/buy/{city}/{type}/?page={n}` | `/buy/phnom-penh/condo/?page=2` | Paginated condos for sale |
| `/rent/{city}/{type}/?page={n}` | `/rent/bkk-1/apartment/?page=1` | Paginated rentals in a commune |
| `/new-developments/{city}/?page={n}` | `/new-developments/phnom-penh/` | Off-plan / pre-sale projects |
| `/buy/{commune}/{N}-bed-{M}-bath-{type}-{id}/` | `/buy/toul-kork/3-bed-3-bath-villa-12345/` | Individual detail page |
| `script#__NEXT_DATA__` | embedded in every page | Hydrated JSON state (richest source) |

#### Extraction strategy

1. **List page** — request HTML, try `__NEXT_DATA__` for structured listings first, fall back to DOM card parsing (`a[href*="/buy/"]` / `a[href*="/rent/"]` selectors with regex extraction of price, beds, baths and area)
2. **URL parsing** — `/buy/{commune}/{N}-bed-{M}-bath-{type}-{id}/` is regex-parsed to recover commune, bed/bath count, property type and listing ID even when the card markup is sparse
3. **Detail page** (optional, set `scrapeDetails: true`) — request the listing URL, parse `pageProps.cacheData.listing.data` for title type, agency, original reference ID, features groups, security & amenities, mainContent description, showCase images, dataGraph coordinates and profile contact info
4. **Pagination** — increment `?page=N` until the response yields zero new listings or `maxPages` / `maxRecords` is hit
5. **Deduplication** — every record is keyed on `propertyId` (falling back to `listingUrl`) so the same listing is never written twice across cities or pages
6. **USD price parser** — strips `$`, commas and flag suffixes (`POA`, `Reduced`, `+`) so prices land in your dataset as clean floats
7. **Relative date parser** — `"3 weeks ago"`, `"6 months ago"` etc. become real ISO-8601 timestamps anchored at run time
8. **Location parser** — splits `"Boeng Keng Kang 1, Chamkar Mon, Phnom Penh"` into `commune` / `district` / `province`
9. **Retry & backoff** — 429s trigger exponential backoff (5s × attempt), non-200 responses retry up to 3 times with linear backoff
10. **Proxy session rotation** — each request rotates an Apify residential proxy session (`session-rkh{N}`) so a single long run won't burn the same IP

***

### Input Parameters

```json
{
  "startUrls": [],
  "listingType": "buy",
  "propertyType": "condo",
  "cities": ["bkk-1", "tonle-bassac"],
  "scrapeDetails": true,
  "maxRecords": 500,
  "maxPages": 0,
  "requestDelay": 1500,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

#### Parameter reference

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | `array<string \| object>` | `[]` | Direct Realestate.com.kh search URLs. When set, all other filters are ignored. |
| `listingType` | `string` | `buy` | One of `buy`, `rent`, `new-developments`, `all`. |
| `propertyType` | `string` | `all` | `all`, `house`, `condo`, `apartment`, `villa`, `land`, `shophouse`, `commercial`, `borey`. |
| `cities` | `array<string>` | `[]` | City or commune slugs as used in the site URL (e.g. `phnom-penh`, `siem-reap`, `sihanoukville`, `bkk-1`, `tonle-bassac`, `toul-kork`, `chamkarmon`, `daun-penh`). Empty array = all Cambodia. |
| `scrapeDetails` | `boolean` | `false` | When `true`, visits each listing's detail page to extract title type (Hard / Soft / Strata), agency, contact phone, coordinates, full image gallery, features, amenities and the description via `__NEXT_DATA__`. Slower, much richer. |
| `maxRecords` | `integer` | `0` | Cap on total listings saved. `0` = unlimited. |
| `maxPages` | `integer` | `0` | Cap on pages per search URL. `0` = unlimited. |
| `requestDelay` | `integer` | `1000` | Milliseconds between requests. `1000`–`2000` recommended. Min `500`, max `10000`. |
| `proxyConfiguration` | `object` | `{ "useApifyProxy": true }` | Apify proxy config — residential is the default and recommended group. The site is not aggressive about bot detection but proxies help on larger runs. |

> **Tip:** Set `scrapeDetails: false` for fast inventory scans (price / beds / area / commune only) and `scrapeDetails: true` when you need title type, agency, contact phone, coordinates or amenities for downstream enrichment.

***

### Output Schema

Every record uses the same flat JSON shape regardless of property type or listing type, so downstream consumers (databases, BI tools, CRMs) can ingest the entire dataset without per-category branching.

#### Core fields

| Field | Type | Description |
|---|---|---|
| `propertyId` | `integer \| null` | Numeric Realestate.com.kh listing ID |
| `originalId` | `string \| null` | Agency's internal reference ID (when published) |
| `title` | `string \| null` | Listing headline |
| `listingType` | `string \| null` | `For Sale`, `For Rent` or `New Development` |
| `propertyType` | `string \| null` | `Condo`, `House`, `Villa`, `Apartment`, `Land`, `Shophouse`, `Commercial`, `Borey`, `Link House`, `Twin Villa`, `Studio`, `Penthouse`, `Flat` |
| `titleType` | `string \| null` | `Hard Title`, `Soft Title`, `Strata Title` or `LMAP` (detail page only) |
| `listingUrl` | `string \| null` | Canonical detail-page URL |

#### Pricing fields (USD)

| Field | Type | Description |
|---|---|---|
| `price` | `number \| null` | Current asking / rent price in USD |
| `originalPrice` | `number \| null` | Pre-discount price when the listing carries a discount ribbon |
| `discountPercent` | `number \| null` | Discount percentage when published |
| `currency` | `string \| null` | Always `USD` — Cambodia residential listings are USD-denominated |
| `priceFlags` | `array \| null` | Ribbons / badges (`Reduced`, `Hot Property`, `Featured`, etc.) |

#### Property attributes

| Field | Type | Description |
|---|---|---|
| `bedrooms` | `integer \| null` | Bedroom count |
| `bathrooms` | `integer \| null` | Bathroom count |
| `floorArea` | `number \| null` | Interior / built-up size in square metres (m²) |
| `landArea` | `number \| null` | Plot size in square metres (m²) — primarily for land, villas and houses |
| `facing` | `string \| null` | Compass facing direction (e.g. `North`, `South-East`) when published |
| `features` | `array \| null` | Property feature labels (`Balcony`, `Open Kitchen`, `River View`, `Maid's Quarters` etc.) |
| `amenities` | `array \| null` | Building/Borey amenity labels (`Swimming Pool`, `Gym`, `Sauna`, `24-Hour Security`, `Underground Parking`) |

#### Location fields

| Field | Type | Description |
|---|---|---|
| `commune` | `string \| null` | Sangkat name (e.g. `Boeng Keng Kang Ti Muoy`, `Tonle Bassac`, `Toul Kork`) |
| `district` | `string \| null` | Khan name (e.g. `Chamkar Mon`, `Daun Penh`, `7 Makara`) |
| `province` | `string \| null` | Province / city name (`Phnom Penh`, `Siem Reap`, `Preah Sihanouk`, `Battambang`, `Kampot`, `Kep`, `Kandal`) |
| `borey` | `string \| null` | Borey (gated community) project name when the listing is inside one |
| `coordinates` | `object \| null` | `{ "lat": 11.5564, "lng": 104.9282 }` GPS coordinates |

#### Agency & contact

| Field | Type | Description |
|---|---|---|
| `agencyName` | `string \| null` | Listing agency or agent name |
| `contactPhone` | `string \| null` | Published contact phone for the agent / agency |

#### Content & media

| Field | Type | Description |
|---|---|---|
| `description` | `string \| null` | Full listing description (detail page only) |
| `images` | `array<string> \| null` | Image URLs from the gallery (`images.realestate.com.kh` CDN) |

#### Timestamps

| Field | Type | Description |
|---|---|---|
| `listedAt` | `string \| null` | ISO-8601 — when the listing was first published (computed from the site's relative date) |
| `updatedAt` | `string \| null` | ISO-8601 — when the listing was last edited |
| `scrapedAt` | `string \| null` | ISO-8601 — when this actor pulled the record |

#### Example: Phnom Penh condo for sale

```json
{
  "propertyId": 1283456,
  "originalId": "REKH-PP-CON-0042",
  "title": "2-Bedroom Condo with River View in Tonle Bassac",
  "listingType": "For Sale",
  "propertyType": "Condo",
  "titleType": "Strata Title",
  "price": 215000,
  "originalPrice": 235000,
  "discountPercent": 8.5,
  "currency": "USD",
  "priceFlags": ["Reduced", "Featured"],
  "bedrooms": 2,
  "bathrooms": 2,
  "floorArea": 78.5,
  "landArea": null,
  "facing": "South-East",
  "commune": "Tonle Bassac",
  "district": "Chamkar Mon",
  "province": "Phnom Penh",
  "borey": null,
  "features": ["Balcony", "River View", "Open Kitchen", "Furnished"],
  "amenities": ["Swimming Pool", "Gym", "24-Hour Security", "Underground Parking", "Elevator"],
  "agencyName": "IPS Cambodia",
  "contactPhone": "+855 12 345 678",
  "description": "Modern 2-bed condo on the 18th floor with unobstructed views over the Tonle Bassac and Mekong rivers...",
  "images": [
    "https://images.realestate.com.kh/listings/1283456/main.jpg",
    "https://images.realestate.com.kh/listings/1283456/02.jpg"
  ],
  "coordinates": { "lat": 11.5471, "lng": 104.9301 },
  "listingUrl": "https://www.realestate.com.kh/buy/tonle-bassac/2-bed-2-bath-condo-1283456/",
  "listedAt": "2026-04-19T00:00:00.000Z",
  "updatedAt": "2026-05-08T00:00:00.000Z",
  "scrapedAt": "2026-05-16T10:42:11.000Z"
}
```

#### Example: Siem Reap villa for rent

```json
{
  "propertyId": 998877,
  "originalId": null,
  "title": "4-Bedroom Pool Villa near Wat Bo, Siem Reap",
  "listingType": "For Rent",
  "propertyType": "Villa",
  "titleType": "Hard Title",
  "price": 1800,
  "currency": "USD",
  "priceFlags": null,
  "bedrooms": 4,
  "bathrooms": 4,
  "floorArea": 320,
  "landArea": 600,
  "commune": "Sala Kamreuk",
  "district": "Siem Reap",
  "province": "Siem Reap",
  "borey": null,
  "features": ["Private Pool", "Garden", "Western Kitchen", "Furnished"],
  "amenities": ["24-Hour Security", "Parking", "Garden"],
  "agencyName": "Angkor Properties",
  "contactPhone": "+855 17 999 888",
  "coordinates": { "lat": 13.3536, "lng": 103.8616 },
  "listingUrl": "https://www.realestate.com.kh/rent/sala-kamreuk/4-bed-4-bath-villa-998877/",
  "scrapedAt": "2026-05-16T10:42:14.000Z"
}
```

***

### Listing Type Reference

| Value | Site Section | Meaning |
|---|---|---|
| `buy` | `/buy/` | Properties for sale (resale and pre-sale) |
| `rent` | `/rent/` | Long-term rentals — apartments, condos, villas, shophouses, commercial |
| `new-developments` | `/new-developments/` | Off-plan / pre-sale projects with developer-level information |
| `all` | combined | Scrapes `buy` + `rent` sequentially |

### Property Type Reference

| Value | Khmer Market Note |
|---|---|
| `house` | Single-family or link house; common across Phnom Penh outskirts and provinces |
| `condo` | The dominant foreign-buyer asset class — high-rise condominiums (Strata Title) |
| `apartment` | Long-term rental apartments, primarily in BKK1, BKK3, Toul Kork and Chamkarmon |
| `villa` | Detached or twin villa — Toul Kork, Chamkarmon and Borey gated estates |
| `land` | Land plots (Hard / Soft Title); critical for developers and hotel buyers |
| `shophouse` | The classic Cambodian commercial-residential row building |
| `commercial` | Office, retail and mixed-use commercial inventory |
| `borey` | Gated, master-planned community housing — a uniquely Cambodian asset |

### Title Type Reference

Cambodia's land-title system is unique in Southeast Asia and is the single biggest factor in foreign-investor due diligence.

| Title Type | Foreign-Eligible? | Description |
|---|---|---|
| `Hard Title` | Local nationals only (land) | National-level title issued by the Ministry of Land Management. Strongest legal protection. |
| `Soft Title` | Local nationals only | District / commune-level title. Most common historically; weaker than Hard Title. |
| `Strata Title` | **Yes** (foreigners) | Co-ownership title for condominium units above the ground floor — the **only** title type foreigners may directly own. |
| `LMAP` | Local nationals only | Land Management and Administration Project — modernised systematic title; effectively equivalent to Hard Title. |

> Foreigners can **lease** Hard / Soft Title properties (up to 50 years renewable) or hold via a Cambodian-majority **landholding company / nominee structure**. Strata Title condos are the cleanest direct-ownership path.

***

### Use Cases

#### Foreign Investor Property Research

International investors weighing Cambodia exposure use this dataset to:

- **Filter by `titleType: Strata Title`** to isolate foreign-eligible condominium stock
- **Map condo pricing per square metre** across BKK1, Tonle Bassac, Toul Kork, Daun Penh and Chamkarmon to spot under-priced micro-markets
- **Compare resale vs pre-sale prices** in the same building (run once with `listingType: buy`, once with `listingType: new-developments`)
- **Track yield potential** by joining `buy` and `rent` runs for the same commune to calculate gross rental yield
- **Build a deal-flow alert pipeline** by scheduling daily runs and diffing against the previous day for new listings, price drops or status changes

#### Chinese Investor & Sihanoukville Market Intelligence

Sihanoukville's transformation around Chinese capital, casino and hotel development is one of the most dramatic real estate stories in Asia. Funds, family offices and journalists use this dataset to:

- **Monitor Sihanoukville inventory in real time** — `cities: ["sihanoukville"]` returns the full active stock
- **Track price recovery / decline** through monthly snapshots after the post-online-gambling-ban correction
- **Identify distressed assets** by filtering for `priceFlags: ["Reduced"]` or large `discountPercent` values
- **Map coastal commune coverage** — Buon, Pir, Bei, Otres, Independence Beach — using `commune` field
- **Trace agency / developer activity** through the `agencyName` field on detail pages

#### Expat & Digital Nomad Relocation

Relocation services, expat-focused property platforms and digital-nomad communities (Hacker Paradise, NomadList, Outsite) consume this dataset to:

- **Curate Phnom Penh rentals** in BKK1, BKK3, Tonle Bassac, Toul Kork and Chamkarmon — the expat heartland
- **Filter furnished apartments under $X / month** for short-stay nomads
- **Surface Siem Reap pool villas** for remote workers wanting Angkor-adjacent lifestyle
- **Highlight Kep and Kampot rentals** for the slow-travel / lifestyle segment
- **Enrich relocation guides** with current price data per neighbourhood and property type

#### Condominium Pre-Sale & Resale Comps

Developers, valuers, brokers and pre-sale resellers use the dataset to:

- **Build per-building price-per-m² benchmarks** by grouping listings on `borey` / project name
- **Compare pre-sale (off-plan) pricing** in `new-developments` against equivalent resale condos
- **Identify under-priced units** in projects where multiple listings exist
- **Track absorption rate** — count active listings per project over time
- **Power valuation models** with floor area, bed count, district and amenities as features

#### Hotel, Resort & Boutique Acquisition Due Diligence

Hospitality investors evaluating Cambodia entry — Phnom Penh boutique, Siem Reap riad-style, Kampot waterfront, Kep oyster-coast, Sihanoukville beachfront — use this dataset to:

- **Source acquisition targets** by filtering `propertyType: commercial` or `propertyType: villa` with high `landArea`
- **Build market comps** for hotel valuation in tertiary markets
- **Identify land plots** suitable for greenfield development with `titleType: Hard Title` filter
- **Track listed inventory turnover** as a market-health indicator
- **Cross-reference agency footprints** to identify dominant local advisors

#### Borey & Gated-Community Market Analytics

Cambodia's Borey segment (Peng Huoth, Vimean Phnom Penh, Chip Mong, Williams Land, Maha Sen Sok, etc.) is a uniquely local asset class. Borey developers, secondary-market brokers and lenders use this dataset to:

- **Inventory active Borey listings** per project using the `borey` field
- **Benchmark pricing** of Link Houses, Twin Villas and Queen Villas within and across Borey brands
- **Monitor secondary-market activity** for primary-sale developers measuring after-market liquidity
- **Power loan-to-value models** for mortgage providers underwriting Borey purchases
- **Track new Borey launches** via `listingType: new-developments` + `propertyType: borey`

#### Real Estate Tech & Proptech Builders

Cambodian and regional proptech startups (rental marketplaces, mortgage calculators, valuation AVMs, virtual-tour platforms) use the dataset to:

- **Bootstrap inventory** without negotiating direct partnerships with every agency
- **Train ML models** on title type, location, area and price to predict valuations
- **Power "compare similar listings"** features inside their own apps
- **Build neighbourhood pages** with live counts of active rentals / sales per commune
- **Detect duplicate listings** across agencies for inventory hygiene

#### Market Research, Macro & Journalism

Bloomberg, Nikkei Asia, Khmer Times, Phnom Penh Post stringers and macro analysts at HSBC, Knight Frank, CBRE and Colliers use Realestate.com.kh as the de-facto Cambodia property barometer:

- **Quantify listing volume trends** as a leading indicator of market sentiment
- **Track median asking price** per commune for quarterly reports
- **Monitor foreign-vs-local share** by filtering on Strata Title proportion
- **Visualise the BKK1 condo pipeline** via `new-developments` runs
- **Investigate Sihanoukville recovery** with longitudinal pricing snapshots

#### Compliance, AML & Sanctions Screening

Banks, escrow providers and law firms supporting Cambodia real estate transactions use the dataset for:

- **Beneficial-ownership research** by aggregating which agencies handle high-value listings
- **Source-of-funds documentation** support with verifiable market-rate price comps
- **Suspicious-pricing detection** — listings priced wildly above or below market may indicate value-transfer mechanisms
- **Cross-border KYC** for Chinese, Vietnamese, Korean and Singaporean buyers

#### Academic & Development Economics Research

Universities (RUPP, Pannasastra, NUS, Sciences Po), the World Bank, ADB and OECD use Cambodia real estate microdata to:

- **Study urbanisation and gentrification** in Phnom Penh communes
- **Quantify foreign-capital footprint** in Sihanoukville and BKK1
- **Research land titling reform** through observable Hard / Soft / Strata distribution
- **Inform housing-affordability policy** with market-asking-price baselines
- **Track post-pandemic tourism recovery** through Siem Reap and coastal listing activity

***

### Sample Queries & Recipes

#### Recipe 1 — All Phnom Penh condos for sale, full detail

Foreign-investor inventory scan with full Hard / Strata Title, agency, coordinates and amenities.

```json
{
  "listingType": "buy",
  "propertyType": "condo",
  "cities": ["phnom-penh"],
  "scrapeDetails": true,
  "maxRecords": 0
}
```

#### Recipe 2 — BKK1 furnished apartments for rent (expat / nomad)

```json
{
  "listingType": "rent",
  "propertyType": "apartment",
  "cities": ["bkk-1", "bkk-3", "tonle-bassac"],
  "scrapeDetails": true,
  "maxRecords": 300
}
```

#### Recipe 3 — Sihanoukville distressed-asset sweep

```json
{
  "listingType": "buy",
  "propertyType": "all",
  "cities": ["sihanoukville"],
  "scrapeDetails": true,
  "maxRecords": 0
}
```

Then filter downstream for distress signals:

```python
distressed = [
    r for r in records
    if (r.get("discountPercent") or 0) >= 10
    or "Reduced" in (r.get("priceFlags") or [])
    or (r.get("price") and r["price"] < 50000 and r.get("propertyType") == "Condo")
]
```

#### Recipe 4 — Siem Reap pool villas (lifestyle / boutique hotel scouting)

```json
{
  "listingType": "buy",
  "propertyType": "villa",
  "cities": ["siem-reap"],
  "scrapeDetails": true
}
```

#### Recipe 5 — Pre-sale / off-plan project intelligence

```json
{
  "listingType": "new-developments",
  "propertyType": "all",
  "cities": ["phnom-penh", "sihanoukville"],
  "scrapeDetails": true
}
```

#### Recipe 6 — Cambodia-wide land for sale (Hard Title only after filter)

```json
{
  "listingType": "buy",
  "propertyType": "land",
  "cities": [],
  "scrapeDetails": true,
  "maxRecords": 0
}
```

Post-filter for Hard Title only:

```python
hard_title_land = [r for r in records if r.get("titleType") == "Hard Title"]
```

#### Recipe 7 — Toul Kork & Chamkarmon villa comps

```json
{
  "listingType": "buy",
  "propertyType": "villa",
  "cities": ["toul-kork", "chamkarmon"],
  "scrapeDetails": true
}
```

#### Recipe 8 — Quick 50-record sample run

```json
{
  "listingType": "buy",
  "propertyType": "condo",
  "cities": ["bkk-1"],
  "maxRecords": 50,
  "scrapeDetails": false
}
```

***

### Integration Examples

#### Google Sheets (via Apify Integration)

1. Schedule the actor daily at 7:00 AM Phnom Penh time (`0 0 * * *` UTC)
2. Add the **"Save to Google Sheets"** integration to the schedule
3. Get a fresh Cambodia condo / villa / land sheet every morning — perfect for brokerage dashboards or investor weekly updates

#### Make.com / Zapier / n8n

The Apify connector is available on every major automation platform. Trigger downstream workflows on:

- **New listings** — diff today's run against yesterday's, push a Slack alert for any condo under $150K in BKK1
- **Price drops** — fire a CRM task when a watched listing's `price` falls
- **Status flips** — alert when an active listing disappears (likely sold)
- **Agency activity spikes** — email a weekly digest of top-5 agencies by new-listing count

#### Power BI / Tableau / Looker / Metabase

Point your BI tool at the Apify dataset REST endpoint. Refresh nightly. Build dashboards covering:

- Median USD/m² by commune over time
- Phnom Penh BKK1 vs. Tonle Bassac condo absorption rates
- Sihanoukville inventory and pricing trend (post-2019 baseline)
- New-development project pipeline by developer
- Borey market activity heat-map

#### Postgres / Snowflake / BigQuery

Use Apify's [webhook integration](https://docs.apify.com/platform/integrations/webhooks) to POST run results to your warehouse ingestion endpoint after every scheduled run, or pull via the dataset API:

```python
import psycopg2
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
conn = psycopg2.connect("postgresql://user:pass@host/cambodia_re")

run = client.actor("haketa/realestate-com-kh-scraper").last_run(status="SUCCEEDED")
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
    conn.cursor().execute("""
        INSERT INTO listings (property_id, title, price_usd, commune, province, listing_type, title_type, scraped_at)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
        ON CONFLICT (property_id) DO UPDATE
          SET price_usd = EXCLUDED.price_usd, scraped_at = EXCLUDED.scraped_at;
    """, (r["propertyId"], r["title"], r["price"], r["commune"], r["province"],
          r["listingType"], r["titleType"], r["scrapedAt"]))
conn.commit()
```

#### Salesforce / HubSpot CRM Enrichment

Trigger a nightly run filtered to your sales territory (e.g. `cities: ["bkk-1", "toul-kork"]`), then upsert against Account records keyed on `agencyName`. Property price changes can auto-create Tasks or trigger nurture workflows for active investor leads.

#### QGIS / Mapbox / Kepler.gl

`coordinates` makes every listing instantly mappable. Drop the dataset JSON into Kepler.gl for a one-click interactive Phnom Penh price heat-map; render in QGIS for cartography-quality output for investor decks and IM (information memorandum) documents.

***

### Major Cambodian Markets Covered

| Province / City | Headline Communes / Areas | Market Note |
|---|---|---|
| **Phnom Penh** | BKK1, BKK3, Tonle Bassac, Toul Kork, Daun Penh, Chamkarmon, 7 Makara, Russey Keo, Sen Sok | Capital & dominant condo / commercial market — the foreign-investor centre of gravity |
| **Siem Reap** | Sala Kamreuk, Svay Dangkum, Sla Kram, Chreav, Kouk Chak | Tourism & boutique hospitality — Angkor Wat-driven villa and guesthouse market |
| **Sihanoukville (Preah Sihanouk)** | Buon, Pir, Bei, Otres, Independence Beach, Ream | Coastal / casino / Chinese-investor market, condo and beachfront stock |
| **Battambang** | Svay Por, Rattanak, Tomnob Tek Pos | Cambodia's second city — affordable, agricultural-region commercial hub |
| **Kampot** | Krong Kampot, Kampong Bay | Riverside lifestyle market, durian-country, expat retirement destination |
| **Kep** | Kep, Sangkat Prey Thom | Coastal lifestyle and boutique resort market — pepper-coast tourism |
| **Kandal** | Ta Khmau, Sa'ang, Kien Svay | Phnom Penh commuter belt — Borey / villa expansion zone |
| **Kampong Cham** | Krong Kampong Cham | Mekong river city, agricultural and trading hub |
| **Pursat / Kampong Speu / Kampong Chhnang** | Provincial capitals | Emerging secondary markets, agricultural land focus |
| **Mondulkiri / Ratanakiri** | Sen Monorom, Banlung | Highland / eco-tourism land and resort opportunities |

Submit a city or commune slug exactly as it appears in the `realestate.com.kh` URL (e.g. `phnom-penh`, `siem-reap`, `sihanoukville`, `bkk-1`, `tonle-bassac`, `toul-kork`, `chamkarmon`, `daun-penh`, `7-makara`, `sen-sok`).

***

### Cost & Performance

| Metric | Value |
|---|---|
| Engine | `got-scraping` HTTP + Cheerio + `__NEXT_DATA__` parser — no headless browser |
| Runtime (50 listings, no detail) | ~30–60 seconds |
| Runtime (500 listings, no detail) | ~3–6 minutes |
| Runtime (500 listings, with detail) | ~12–25 minutes (depends on `requestDelay`) |
| Pricing model | Pay-per-event (transparent per-record pricing) |
| Data freshness | Live at run time — direct fetch from realestate.com.kh |
| Auth required | None |
| Proxy required | Recommended for `>200` listings; defaults to Apify residential |
| Concurrency | Safe to run multiple filtered configurations in parallel (e.g. one per city) |
| Memory footprint | 256 MB sufficient — `minMemoryMbytes: 128`, `maxMemoryMbytes: 1024` |
| Retry policy | Up to 3 attempts per URL with exponential backoff on 429 |

***

### Compliance, Privacy & Legal Notes

- **Public data only** — every field surfaced by this actor is already published on the public `realestate.com.kh` listing pages, available to any visitor without login or paywall
- **No PII / no buyer data** — the actor returns agency / agent listing contacts (which the agents have voluntarily published as part of the listing) and never user, buyer, viewer or registration data
- **No PHI / no financial records** — purely property-listing data
- **Respect the source** — do not republish copyrighted descriptions or images verbatim without permission; transformative analytics, internal dashboards and aggregated market reports are the standard fair-use pattern
- **Robots / ToS** — the actor obeys polite request pacing (default 1000 ms delay, configurable) and ships no aggressive concurrency settings. Review [Realestate.com.kh's Terms of Use](https://www.realestate.com.kh/terms/) before high-volume runs
- **Cambodian data protection** — Cambodia has no comprehensive data-protection law equivalent to GDPR, but agency contact data should still be handled with reasonable care
- **GDPR / CCPA** — compliance for downstream consumers in the EU / California is the responsibility of the data controller, not the actor
- **No anti-competition** — the actor is intended for market intelligence, due diligence, research and aggregation, not for unauthorised scraping to undermine the source platform

> **Important:** This data may not be used for unlawful purposes including but not limited to harassment, identity fraud, or violation of Cambodian land-ownership restrictions. Investor and developer users should consult licensed Cambodian counsel for title verification, foreign-ownership structuring and KYC obligations.

***

### Frequently Asked Questions

#### How fresh is the data?

The actor scrapes **live at run time** — every record reflects what's on `realestate.com.kh` the moment the actor runs. Schedule it hourly, daily or weekly to build a time series.

#### How many listings will I get?

Varies — Realestate.com.kh hosts **tens of thousands** of active listings across all Cambodia at any time. A nationwide unfiltered run (`cities: []`, `listingType: all`, `propertyType: all`) returns the bulk of the inventory; a filtered run (e.g. `condo` in `bkk-1`) returns hundreds. Set `maxRecords` to cap; leave it `0` for unlimited.

#### Does this scraper need a login or API key?

No. Realestate.com.kh listings are public — no authentication required. You only need an Apify account to run the actor.

#### Are prices in USD or KHR (Khmer Riel)?

**USD.** Cambodia's real estate market is fully dollarised; the site publishes all prices in US dollars and the actor's `currency` field is always `"USD"`. Convert to KHR downstream if you need it (1 USD ≈ 4,100 KHR).

#### What's the difference between Hard Title, Soft Title and Strata Title?

**Hard Title** is national-level land title (strongest legal protection). **Soft Title** is district / commune-level (most common historically). **Strata Title** is condominium co-ownership — the **only** title type foreigners may directly own. **LMAP** titles are modernised systematic Hard Titles. See the **Title Type Reference** table above.

#### Can foreigners buy property in Cambodia?

Foreigners can directly own **condominium units above the ground floor** with **Strata Title**. Other property types require leasing structures or Cambodian-majority landholding companies. Filter `titleType: "Strata Title"` to isolate foreign-eligible inventory.

#### Does it cover Sihanoukville's Chinese-investor market?

Yes — set `cities: ["sihanoukville"]` and the actor returns all active inventory across Sangkat Buon, Pir, Bei, Otres and Independence Beach. Pair with `priceFlags` and `discountPercent` filters to flag distressed assets from the post-2019 correction.

#### Does it include Borey (gated-community) listings?

Yes. Set `propertyType: "borey"` for the dedicated Borey category, or look at the `borey` field on individual house / villa records to see which gated community a listing belongs to. New Borey launches are also surfaced via `listingType: "new-developments"`.

#### Can I get agency phone numbers and contact details?

Yes — when `scrapeDetails: true`, the actor pulls `agencyName` and `contactPhone` from the listing detail page's `__NEXT_DATA__` profiles section. Without detail scraping, list-level data may be sparser.

#### Are coordinates / map pins included?

Yes — when `scrapeDetails: true`, the `coordinates` object is populated from the detail page's `dataGraph` block. Without detail scraping coordinates are usually `null`.

#### Does the actor cover pre-sale / off-plan condos?

Yes — set `listingType: "new-developments"` to scrape Realestate.com.kh's dedicated new-developments section, which surfaces off-plan condo, villa and Borey projects with developer-level information.

#### Can I run this on a schedule?

Yes — Apify's Scheduler supports any cron expression. Common patterns: hourly for hot-market price tracking, daily at 7 AM Phnom Penh time for brokerage dashboards, weekly for market reports.

#### Does the actor deduplicate?

Yes. Records are deduped by `propertyId` (falling back to `listingUrl`) so the same listing is never written twice across overlapping searches, cities or paginated pages.

#### Does it handle CAPTCHAs?

Realestate.com.kh does not deploy aggressive CAPTCHA / anti-bot today. The actor uses realistic browser fingerprints via `got-scraping`, randomised Apify residential proxy sessions and configurable per-request delay, which together avoid the rate-limit thresholds in normal use. Reduce concurrency and increase `requestDelay` if you see 429 responses.

#### What if Realestate.com.kh changes its HTML?

The actor uses a layered strategy: `__NEXT_DATA__` JSON extraction first, DOM card parsing second, URL regex parsing third. Minor markup changes typically don't break the extractor. Major Next.js bundle restructures are patched in subsequent versions — open an issue if you see a regression.

#### What export formats are supported?

JSON, CSV, Excel (XLSX), HTML, XML, RSS and JSON Lines — directly from the Apify dataset view or via the API.

#### Does it work on the Apify free plan?

Yes — full functionality on the free tier. Costs are pay-per-event, and most small filtered runs cost cents.

#### Can I scrape only one Borey project?

Use `startUrls` with the Borey project's search URL on the site (e.g. a filtered search for a specific Borey name), or post-filter the records by the `borey` field.

#### Are commercial / office listings included?

Yes — set `propertyType: "commercial"` for office, retail and mixed-use commercial inventory across Phnom Penh, Sihanoukville and Siem Reap.

#### Does it support other Cambodian portals (Khmer24, ip.cambodia.com)?

Not in this actor — it's purpose-built for Realestate.com.kh's specific Next.js architecture. See the **Related Actors** section for our Southeast Asia portfolio (Lamudi Philippines, VivaReal Brazil, Chotot Vietnam, Mudah Malaysia) and ask in the Issues tab if you'd like Khmer24 coverage added.

***

### Related Apify Actors by Haketa

If you build cross-border real estate, marketplace or location intelligence pipelines, these sibling actors are useful complements:

#### Real estate — Southeast Asia & adjacent

- [Lamudi Philippines Real Estate Scraper](https://apify.com/haketa/lamudi-scraper) — Manila, Cebu, Davao condo / land inventory
- [Chotot.com Scraper (Vietnam)](https://apify.com/haketa/chotot-scraper) — Vietnam's largest classifieds (HCMC, Hanoi, Da Nang) including property
- [Mudah.my Scraper (Malaysia)](https://apify.com/haketa/mudah-scraper) — Malaysian classifieds with extensive property category
- [Zameen.com Pakistan Real Estate Scraper](https://apify.com/haketa/zameen-scraper) — Karachi, Lahore, Islamabad inventory
- [VivaReal Brazil Real Estate Scraper](https://apify.com/haketa/vivareal-scraper) — São Paulo, Rio de Janeiro residential
- [ZAP Imóveis Brazil Scraper](https://apify.com/haketa/zapimoveis-scraper) — sister Brazilian portal to VivaReal

#### Real estate — global

- [Realtor.ca Scraper (Canada)](https://apify.com/haketa/realtor-ca-scraper) — Canadian MLS-fed inventory
- [Domain.com.au Property Scraper (Australia)](https://apify.com/haketa/domain-com-au-scraper) — Sydney, Melbourne, Brisbane
- [Immoweb.be Belgium Property Scraper](https://apify.com/haketa/immoweb-scraper) — Brussels, Antwerp, Ghent
- [Apartments.com Scraper (US)](https://apify.com/haketa/apartments-com-scraper) — US rental inventory
- [Rent.com Scraper (US)](https://apify.com/haketa/rent-com-scraper) — US rentals

#### Marketplaces & classifieds (regional Southeast Asia)

- [TradeMe Scraper (New Zealand)](https://apify.com/haketa/trademe-scraper) — NZ classifieds
- [Mourjan Scraper (MENA)](https://apify.com/haketa/mourjan-scraper) — Middle East / North Africa classifieds

***

### Comparison vs. Alternatives

| Approach | Setup time | Data freshness | Schema normalization | USD price parsing | Title-type extraction | Maintenance burden |
|---|---|---|---|---|---|---|
| **This actor** | < 2 minutes | Live | Built-in | Built-in | Built-in (detail mode) | None — managed |
| Custom Cheerio/Puppeteer script | 1–3 weeks of dev | Live | DIY | DIY | DIY | Continuous — Next.js bundle changes break parsers |
| Hire a local Cambodian dev | Days to weeks | Variable | DIY | DIY | DIY | Ongoing labour cost |
| Manual copy-paste from website | Hours per pull | Live | None | None | None | Doesn't scale |
| Negotiate API access with portal | Weeks to months | Variable | Provided | Provided | Provided | Commercial agreement required |
| Buy a market-report PDF | Days | Quarterly / stale | N/A | N/A | N/A | Snapshot only — no time series |

***

### Why Pay-Per-Event Pricing?

Most scraping tools either charge a flat monthly subscription (you pay even if you don't use it) or per-Compute-Unit (unpredictable). This actor uses **pay-per-event** pricing:

- You only pay when the actor actually runs and produces records
- Charges scale with how much data you consume — a 50-record test costs cents
- Transparent, line-item billing in Apify Console
- No monthly minimums, no platform lock-in
- Free to evaluate — run a `maxRecords: 50` sample before committing

***

### Changelog

| Version | Date | Notes |
|---|---|---|
| 1.0.0 | 2026-05 | Initial public release — `got-scraping` + Cheerio + `__NEXT_DATA__` parser, full pagination, optional detail-page enrichment with Hard / Soft / Strata Title, agency, contact phone, coordinates, features and amenities |

***

### Keywords

Realestate.com.kh scraper · Cambodia real estate data · Cambodia property scraper · Phnom Penh property scraper · Phnom Penh condo scraper · BKK1 condo prices Cambodia · Tonle Bassac condo data · Toul Kork villa scraper · Chamkarmon real estate data · Daun Penh property listings · Siem Reap property data · Siem Reap villa scraper · Sihanoukville property scraper · Sihanoukville Chinese investor data · Battambang real estate scraper · Kampot property data · Kep coastal real estate · Kandal property listings · Khmer property listings extractor · Cambodia real estate API · Cambodia property listings API · Cambodia foreign investor property · Strata Title Cambodia scraper · Hard Title land Cambodia · Soft Title property data · Borey gated community scraper · Cambodia condo pre-sale data · Cambodia new developments scraper · Cambodia rental listings · Phnom Penh expat apartments · Cambodia digital nomad rentals · Cambodia commercial property data · Cambodia land for sale scraper · Cambodia shophouse listings · Cambodia real estate market intelligence · Apify Cambodia actor · Southeast Asia property scraper · realestate.com.kh data extraction · Cambodia condo comps · Phnom Penh price per square metre · Sihanoukville beachfront data · USD property listings Cambodia · Cambodia agency contact data · Cambodia hotel acquisition due diligence · Cambodia property data warehouse · Phnom Penh property analytics

***

### Support

- **Bug reports:** Use the **Issues** tab on the [Apify Store page](https://apify.com/haketa/realestate-com-kh-scraper)
- **Feature requests:** Same place — tell us the use case and the city / commune / property type
- **Direct contact:** Through the Apify developer profile at [apify.com/haketa](https://apify.com/haketa)

If this actor saves you time on Cambodia real estate research, a **5-star rating** on the Apify Store helps other investors, brokers, journalists, hospitality acquirers and proptech teams discover it. Thank you — អរគុណ!

# Actor input Schema

## `startUrls` (type: `array`):

Direct search URLs. Overrides other filters. Example: 'https://www.realestate.com.kh/buy/phnom-penh/condo/'

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

Buy, rent or new developments.

## `propertyType` (type: `string`):

Type of property.

## `cities` (type: `array`):

City or area slugs. Examples: 'phnom-penh', 'siem-reap', 'sihanoukville', 'bkk-1', 'tonle-bassac', 'toul-kork'. Leave empty for all Cambodia.

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

Visit each listing for full description, features, amenities, coordinates, all images, title type (Hard/Soft/Strata) and agency info via **NEXT\_DATA**. Much richer data.

## `maxRecords` (type: `integer`):

Maximum total listings. Set 0 for unlimited.

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

Maximum pages per search. Set 0 for unlimited.

## `requestDelay` (type: `integer`):

Delay between requests. 1000-2000ms recommended.

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

Proxy recommended for large scrapes. Site is not aggressive with bot detection.

## Actor input object example

```json
{
  "startUrls": [],
  "listingType": "buy",
  "propertyType": "all",
  "cities": [],
  "scrapeDetails": false,
  "maxRecords": 50,
  "maxPages": 0,
  "requestDelay": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `propertyId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `propertyType` (type: `string`):

No description

## `price` (type: `string`):

No description

## `titleType` (type: `string`):

No description

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

No description

## `floorArea` (type: `string`):

No description

## `commune` (type: `string`):

No description

## `province` (type: `string`):

No description

## `listingUrl` (type: `string`):

No description

## `scrapedAt` (type: `string`):

No description

# 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 = {
    "startUrls": [],
    "listingType": "buy",
    "propertyType": "all",
    "cities": [],
    "scrapeDetails": false,
    "maxRecords": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/realestate-com-kh-scraper").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 = {
    "startUrls": [],
    "listingType": "buy",
    "propertyType": "all",
    "cities": [],
    "scrapeDetails": False,
    "maxRecords": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/realestate-com-kh-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [],
  "listingType": "buy",
  "propertyType": "all",
  "cities": [],
  "scrapeDetails": false,
  "maxRecords": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/realestate-com-kh-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=haketa/realestate-com-kh-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Realestate.com.kh Scraper | Cambodia Property Listings",
        "description": "Scrape Cambodia's #1 property portal realestate.com.kh. Houses, condos, land & villas in Phnom Penh & Siem Reap. USD prices, Hard/Strata Title, Borey filter & foreign-eligible listings.",
        "version": "0.0",
        "x-build-id": "YYc0PEHvwz5mCqnuA"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/haketa~realestate-com-kh-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-haketa-realestate-com-kh-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/haketa~realestate-com-kh-scraper/runs": {
            "post": {
                "operationId": "runs-sync-haketa-realestate-com-kh-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/haketa~realestate-com-kh-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-haketa-realestate-com-kh-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Direct search URLs. Overrides other filters. Example: 'https://www.realestate.com.kh/buy/phnom-penh/condo/'",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "listingType": {
                        "title": "Listing Type",
                        "enum": [
                            "buy",
                            "rent",
                            "new-developments",
                            "all"
                        ],
                        "type": "string",
                        "description": "Buy, rent or new developments.",
                        "default": "buy"
                    },
                    "propertyType": {
                        "title": "Property Type",
                        "enum": [
                            "all",
                            "house",
                            "condo",
                            "apartment",
                            "villa",
                            "land",
                            "shophouse",
                            "commercial",
                            "borey"
                        ],
                        "type": "string",
                        "description": "Type of property.",
                        "default": "all"
                    },
                    "cities": {
                        "title": "Cities / Areas",
                        "type": "array",
                        "description": "City or area slugs. Examples: 'phnom-penh', 'siem-reap', 'sihanoukville', 'bkk-1', 'tonle-bassac', 'toul-kork'. Leave empty for all Cambodia.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "scrapeDetails": {
                        "title": "Scrape Detail Pages",
                        "type": "boolean",
                        "description": "Visit each listing for full description, features, amenities, coordinates, all images, title type (Hard/Soft/Strata) and agency info via __NEXT_DATA__. Much richer data.",
                        "default": false
                    },
                    "maxRecords": {
                        "title": "Max Records",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum total listings. Set 0 for unlimited.",
                        "default": 0
                    },
                    "maxPages": {
                        "title": "Max Pages",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum pages per search. Set 0 for unlimited.",
                        "default": 0
                    },
                    "requestDelay": {
                        "title": "Request Delay (ms)",
                        "minimum": 500,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Delay between requests. 1000-2000ms recommended.",
                        "default": 1000
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy recommended for large scrapes. Site is not aggressive with bot detection."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
