# 28hse.com Hong Kong Property Scraper: Sale, Rent, Estates (`recordsdata/28hse-scraper`) Actor

Scrape 28hse.com, the Hong Kong property portal: sale and rent listings (apartments, offices, shops, car parks, land, overseas homes), estate profiles, deal history and new developments. HKD prices, areas in sq ft and m2, coordinates, agency, photos. Monitor mode. No login. Export JSON, CSV, Excel.

- **URL**: https://apify.com/recordsdata/28hse-scraper.md
- **Developed by:** [RecordsData](https://apify.com/recordsdata) (community)
- **Categories:** Real estate, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $22.00 / 1,000 property listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![RecordsData](https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner?v=3)

## 28hse.com Hong Kong Property Scraper: Sale, Rent, Estates and Transactions

> **28hse.com Hong Kong Property Scraper exports data from 28Hse (28hse.com), a Hong Kong property portal with 42,104 listings for sale and 26,458 for rent on 2026-10-29. One listing row has the price in HKD, saleable and gross area in square feet, bedrooms, address with coordinates, floor, building age, agency and licence number, photos and posting dates. The actor also returns 15,310 estate and building profiles, their sale and rent transaction history, and new home developments. Export JSON, CSV, Excel, XML or HTML. No login, no API key, no browser. Pay per result.**

28Hse (香港屋網) lists apartments, offices, shops, car parks, land and overseas new homes across Hong Kong. This actor reads the public English pages, applies the site search filters, opens every listing page and returns typed rows.

### What can you scrape from 28hse.com?

| Record type (`recordTypes`) | What one row is | Size on 2026-10-29 |
|---|---|---|
| `listings` | One sale or rent ad: price, areas, rooms, address, coordinates, agency, photos, dates | 42,104 for sale and 26,458 for rent |
| `estates` | One housing estate or commercial building: developer, blocks, units, average price per sq ft, rental yield, school nets | 11,621 housing estates and 3,689 commercial buildings |
| `transactions` | One recorded sale or rental deal of an estate: date, price, area, unit, price per sq ft | about 10 rows per estate page, sale and rent |
| `new-developments` | One new home or new office project: developer, status, units on sale, layouts, brochure | about 275 homes and 40 office projects |

Listings by property type on 2026-10-29. For sale: apartments 39,795, offices and industrial 1,488, car parks 444, shops 257, land 91, overseas new homes 29. A listing row has up to 67 fields; the dataset schema defines 113 data fields in total.

### Why use this actor?

- **The whole catalog is reachable.** Page 2,653 of 39,795 apartments for sale still returns listings.
- **Real filters, applied by the site.** Region, district, price, area, bedrooms, bathrooms, direction, floor, building age, advertiser type and sort order go straight into the site search.
- **Four record types in one tool.** Listings, estate profiles, transaction history and new developments, each with its own typed columns.
- **Privacy first.** No private-seller names, phone numbers or emails. Agency phone numbers only appear when you ask for them.

### How to scrape 28hse.com in four steps

1. Create a free account at https://console.apify.com and open the actor.
2. Choose the record types, then add filters such as the operation (sale or rent), property types, a region or district and a price range. Or paste 28hse.com links: a search, a listing, an estate, an estate directory or the new homes list.
3. Set the maximum number of results and click **Start**.
4. Download the dataset from the **Storage** tab as JSON, CSV, Excel, XML or HTML.

### Input

The form has 27 fields. The main ones:

| Field | Type | Default | Meaning |
|---|---|---|---|
| `recordTypes` | array | `["listings"]` | What to collect: `listings`, `estates`, `transactions`, `new-developments` |
| `startUrls` | array | empty | 28hse.com links to read directly; they replace the filters |
| `maxItems` | integer | 10 prefill | Maximum rows (free plans: 10) |
| `maxItemsPerSearch` | integer | 0 | Cap per search or per estate, 0 means no cap |
| `fetchDetails` | boolean | true | Open each page for full description, photos, coordinates, dates |
| `operation` | string | `sale` | `sale`, `rent` or `both` |
| `propertyTypes` | array | empty | `apartment`, `carpark`, `office`, `shop`, `land`, `oversea` |
| `regions` / `districts` | array | empty | Hong Kong regions and district groups |
| `minPrice` / `maxPrice` | number | 0 | Amount in HKD (rent: per month) |
| `minArea` / `maxArea` / `areaBasis` | number / number / string | 0 / 0 / `saleable` | Area in square feet, saleable or gross |
| `bedrooms` / `bathrooms` | array | empty | Room counts to keep |
| `directions` / `floors` / `buildingAge` | array | empty | Facing, floor zone and building age filters |
| `advertisers` | array | empty | Advertiser type |
| `sortBy` / `postedWithinDays` | string / integer | `latest` / 0 | Sort order and maximum posting age |
| `estateKind` | string | `housing` | Housing estates or commercial buildings |
| `includeContactDetails` | boolean | false | Add the agency phone number |
| `maxRunSeconds` | integer | 1800 | Longest run time |
| `onlyNew` / `stateKey` / `resetSeen` | boolean / string / boolean | false / empty / false | Monitor mode, monitor name, reset |

Input for the 20 newest two-bedroom apartments for rent in Wan Chai up to HK$30,000 a month:

```json
{
  "recordTypes": ["listings"],
  "operation": "rent",
  "propertyTypes": ["apartment"],
  "districts": ["wan-chai-admiralty"],
  "maxPrice": 30000,
  "bedrooms": ["2"],
  "sortBy": "latest",
  "maxItems": 20
}
```

### What data do you get from 28hse.com?

Every row has a `recordType`: `listing`, `estate`, `transaction` or `development`. Fields a page does not show are left out. Dates are ISO 8601, amounts are numbers, and lists such as `images` and `features` are real arrays. Example values for estates, transactions and developments are illustrative.

#### Listing fields (`listing`)

| Field | Type | Example |
|---|---|---|
| `listingId` | string | `4074611` |
| `operation` | string | `sale` |
| `price` | number | `8280000` |
| `pricePerSqft` | number | `12680` |
| `areaSqft` | number | `653` |
| `bedrooms` | number | `3` |
| `buildingAgeYears` | number | `26` |
| `region` | string | `New Territories` |
| `district` | string | `Ma On Shan` |
| `estateName` | string | `Mountain Shore` |
| `agencyName` | string | `Mang Tat Property Limited` |
| `publishedAt` | string | `2026-10-29T16:53:12.000Z` |

#### Estate fields (`estate`)

| Field | Type | Example |
|---|---|---|
| `estateName` | string | `Mountain Shore` |
| `url` | string | `https://www.28hse.com/en/estate/detail/mountain-shore-4043` |
| `region` | string | `New Territories` |
| `district` | string | `Ma On Shan` |
| `developer` | string | `Example Developer` |
| `completionYear` | number | `2000` |
| `totalUnits` | number | `3000` |
| `avgPricePerSqft` | number | `12500` |
| `rentalYield` | number | `2.9` |

#### Transaction fields (`transaction`)

| Field | Type | Example |
|---|---|---|
| `transactionId` | string | `1234567` |
| `currency` | string | `HKD` |
| `estateId` | string | `4043` |
| `operation` | string | `sale` |
| `transactionDate` | string | `2026-10-15` |
| `price` | number | `7800000` |
| `currency` | string | `HKD` |
| `areaSqft` | number | `620` |
| `pricePerSqft` | number | `12581` |
| `gainPercent` | number | `18.5` |

#### New development fields (`development`)

| Field | Type | Example |
|---|---|---|
| `title` | string | `Example Residences` |
| `status` | string | `On sale` |
| `developers` | array | `["Example Developer"]` |
| `remainingUnits` | number | `40` |
| `expectedCompletion` | string | `2027-06` |

#### Sample output

One real listing row from a cloud run on 2026-10-29 (photo list and description shortened):

```json
{
  "recordType": "listing",
  "listingId": "4074611",
  "operation": "sale",
  "propertyType": "Apartment",
  "price": 8280000,
  "currency": "HKD",
  "pricePerSqft": 12680,
  "areaSqft": 653,
  "bedrooms": 3,
  "floorZone": "Low Floor",
  "region": "New Territories",
  "district": "Ma On Shan",
  "latitude": 22.411249,
  "longitude": 114.222527,
  "estateName": "Mountain Shore",
  "publishedAt": "2026-10-29T16:53:12.000Z",
  "agencyName": "Mang Tat Property Limited",
  "images": ["https://i1.28hse.com/2026/10/202610300053104553026_large.jpg"],
  "scrapedAt": "2026-10-29T16:54:43.316Z"
}
```

### Monitor new listings

Switch on **Only new rows (monitor mode)** and the actor remembers every row it delivered in a named key-value store called `28hse-seen` in your own Apify account. A scheduled run of the same search then returns only unseen rows. Use **State key** to keep two monitors apart.

### How much does the 28hse.com Scraper cost?

Pay per result, no monthly fee. Rates are USD per result on the Free tier.

| Event | Charged for | Per result | Per 1,000 |
|---|---|---|---|
| Listing record | One sale or rent ad | $0.022 | $22.00 |
| Listing detail record | One listing page opened for full details (`fetchDetails`) | $0.01467 | $14.67 |
| Estate record | One estate or building profile | $0.02933 | $29.33 |
| Estate detail record | One estate page opened for full details | $0.01467 | $14.67 |
| Transaction record | One recorded sale or rental deal | $0.011 | $11.00 |
| Development record | One new home or office project | $0.02933 | $29.33 |

Worked examples: 1,000 listing records cost $22.00. With full details on, each listing also triggers a detail record, so 1,000 detailed listings cost 1,000 x ($0.022 + $0.01467) = $36.67. 1,000 transaction records cost $11.00. 315 new developments cost 315 x $0.02933 = $9.24. Error rows and empty searches are not charged, and monitor mode skips rows you already received.

### How does it compare with other 28hse.com scrapers? (read on 2026-11-03)

| | This actor | fatihtahta/28hse-scraper | realestateapi/28hse-properties-and-details-scraper | claude_code_reviewer/28hse-scraper-en |
|---|---|---|---|---|
| Published output fields | 113 | None published | 64 | 27 |
| Record types | Listings, estates, transactions, new developments | Not stated | Not stated | Not stated |
| Coordinates and school nets | Yes | Not stated | Not stated | Not stated |
| Monitor mode | Built in | Not stated | Not stated | Not stated |
| Total runs and users on the Store | New actor | 238 runs, 8 users | 24 runs, 2 users | 129 runs, 2 users |

The other three read 28hse.com listings; this one adds estate profiles, deal history and new developments, and exposes every filter of the site search. Choose it when you need more than a flat list of ads. A manual export from the site or a generic browser scraper is slower and covers fewer record types.

### Is it legal to scrape 28hse.com? Limits and responsible use

The actor reads publicly visible pages without a login, without solving captchas and without bypassing any protection, at no more than about four requests per second. It follows the robots.txt of 28hse.com and never opens agent profile pages. Names, phone numbers and emails of private sellers are removed from titles and descriptions.

Read this before you build a product on the data: the terms of use of 28hse.com restrict automated collection and supplying the content to third parties. Whether your use is allowed depends on your purpose, your country and the terms you accepted. Check them, and follow the data protection law that applies to you, such as the Hong Kong Personal Data (Privacy) Ordinance.

Limits:

- 28hse.com sits behind Cloudflare, which blocks plain cloud IP addresses. The actor uses Apify datacenter proxies and no browser.
- Overseas new homes show a "HK$" price even when the ad text quotes another currency.
- Free Apify plans are limited to 10 results per run.

### Use with AI agents (MCP)

Connect the Apify MCP server to Claude, Cursor or another MCP client and this actor appears as a tool: `https://mcp.apify.com?tools=RecordsData/28hse-scraper`.

Example prompt: "List the 20 newest 2-bedroom apartments for rent in Wan Chai under HK$30,000 a month, with area, floor and agency." The agent fills the same filters shown in the actor form and analyzes the rows.

### Run it from code

Call the actor with the `apify-client` package for JavaScript or Python, or from Make, Zapier or n8n, and schedule it from the Apify Console.

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('RecordsData/28hse-scraper').call({
    recordTypes: ['listings'],
    operation: 'rent',
    propertyTypes: ['apartment'],
    districts: ['wan-chai-admiralty'],
    maxPrice: 30000,
    bedrooms: ['2'],
    sortBy: 'latest',
    maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]?.price);
```

### Frequently Asked Questions

#### What does the 28hse.com Scraper return?

Up to four kinds of rows: listings for sale and rent, estate and building profiles, sale and rent transactions of an estate, and new home developments. A listing row has up to 67 typed fields, including price in HKD, areas in square feet and square meters, bedrooms, coordinates, agency and photos.

#### Do I need a proxy, a login or an API key?

No login and no API key. Because Cloudflare blocks plain cloud IP addresses, the actor uses Apify datacenter proxies by default, which every Apify account can use. You only need an Apify account, and the free plan returns up to 10 results per run.

#### How many listings can I get in one run?

As many as the filters match and your plan allows. The site search goes past page 2,600 for apartments, so a whole district or even the whole catalog can be collected. Set a maximum number of results to control the cost of a run. Free plans are limited to 10 results.

#### How do I search one district or a price range?

Pick a district or region, then set a minimum and maximum amount in Hong Kong dollars. For sale use full dollars, for example 8000000 for HK$8 million; for rent give the monthly rent. Area is in square feet, and you can switch between saleable and gross area.

#### How is the price stored?

As a number in `price` with `currency` set to `HKD`. Rent rows also carry `rentPeriod: "month"`. The text the site shows, such as "HK$8.28 million", is kept in `priceText`, and `pricePerSqft` and `pricePerM2` are included next to it. Negotiable listings have no number and carry `isPriceNegotiable: true`.

#### Does it return phone numbers and seller names?

No. Names, phone numbers and emails of private sellers are never returned, and agent profile pages are never opened. Agency business data such as name, address and licence number is returned. The agency phone number is added only when you switch on the option **Include agency phone** in the input form.

#### Can I read one listing, one estate or one search from a link?

Yes. Paste a 28hse.com listing, search result, estate page, estate directory or new homes link into the start URLs and the actor reads it directly. When start URLs are given they replace the filters, and links from other sites stop the run with a message that says what to change.

#### Can I get only the newest listings?

Yes. Use monitor mode to receive only rows you have not received before in scheduled runs, or limit the posting age in days and sort by latest, which also lets the scan stop early. A state key keeps two monitors apart.

#### What happens when the search finds nothing or the input is wrong?

A search that matches nothing ends with a clear "no items matched" message and nothing is charged. A wrong input, such as a minimum amount above the maximum or a link from another site, stops the run with a message that says what to change.

### Support

Questions, a missing field or a bug: write to contact.punkrecordsdata@gmail.com and include the run link. Reviews on the actor page help other people find it.

This actor is an independent tool and is not affiliated with 28Hse or 28hse.com.

Last updated: 2026-11-03

# Actor input Schema

## `recordTypes` (type: `array`):

Listings = sale or rent ads. Estates = housing estate or building profiles. Transactions = recorded sales and leases. New developments = primary-market projects. Example: Listings.

## `maxItems` (type: `integer`):

Stops after this many rows, all record types together. Free users are limited to 10 items per run (preview). Example: 50.

## `maxItemsPerSearch` (type: `integer`):

Optional cap for every single search (one operation, property type and place) or, for transactions, for every single estate. It stops one big search from using the whole Max Items budget. 0 means no per-search limit.

## `operation` (type: `string`):

Listings for sale, for rent, or both (both runs every search twice). Transactions follow the same choice: sold units, leased units or both. Rows say which one in the operation field.

## `propertyTypes` (type: `array`):

Categories to search, one search each. Empty means apartments and houses. Overseas new homes are sale-only and live in the Overseas region.

## `regions` (type: `array`):

Hong Kong regions to search, one search each. Empty means all of Hong Kong. Estates are listed by region too.

## `districts` (type: `array`):

District groups to search, one search each (the site groups some small districts together). If you also pick regions, every district must belong to one of them. Empty means the whole region.

## `minPrice` (type: `number`):

Only listings priced at least this much, in Hong Kong dollars (1000000 = HK$1 million; for rent it is the monthly rent). 0 means no limit.

## `maxPrice` (type: `number`):

Only listings priced at most this much, in Hong Kong dollars (8000000 = HK$8 million; for rent it is the monthly rent). 0 means no limit.

## `minArea` (type: `number`):

Only listings with at least this area in square feet (Hong Kong ads are measured in square feet; 1 square meter is 10.76 square feet). 0 means no limit.

## `maxArea` (type: `number`):

Only listings with at most this area in square feet. 0 means no limit.

## `areaBasis` (type: `string`):

Which area the minimum and maximum area apply to. Hong Kong ads usually give a saleable area and a larger gross area.

## `bedrooms` (type: `array`):

Bedroom counts to include. Empty means any.

## `bathrooms` (type: `array`):

Bathroom counts to include. Empty means any.

## `directions` (type: `array`):

Direction the unit faces. Empty means any.

## `floors` (type: `array`):

Floor zone of the unit. Empty means any.

## `buildingAge` (type: `array`):

Age bands of the building. Empty means any.

## `advertisers` (type: `array`):

Who posted the ad: a landlord or owner, a big landlord (developer or institutional owner), or an agency. Empty means all.

## `postedWithinDays` (type: `integer`):

Only listings posted in the last N days, read from the posting label of each search card; for transactions, only deals dated in the last N days. With newest-first order the search stops early. 0 means any age.

## `sortBy` (type: `string`):

Order of the results. Newest first is the default and the only order where "Posted within" and monitor mode can stop early.

## `estateKind` (type: `string`):

Which directory to read for the Estates, Transactions and New developments record types: housing estates and new homes, commercial and industrial buildings and new office projects, or both.

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

A listing, a search page, an estate, an estate directory or the new developments list. Example: https://www.28hse.com/en/rent/apartment. Leave empty to use the search above.

## `fetchDetails` (type: `boolean`):

Open every listing, estate and development page for the full description, all photos, coordinates, floor, building age, management fee, school nets, agency licence and dates. Turn it off for a faster and cheaper run with the fields of the search card only.

## `includeContactDetails` (type: `boolean`):

Add the head office phone number and licence of the agency behind a listing (business data from the agency company page, one extra request per agency). Private landlords and individual agents are never named and their phones and emails are never returned. Off by default.

## `maxRunSeconds` (type: `integer`):

Stop collecting after this many seconds and return what was gathered, so a very wide search never runs unbounded.

## `onlyNew` (type: `boolean`):

Skip every listing, estate, transaction or development this same search already returned in an earlier run, so a scheduled run returns just the new ones and you are not charged for skipped rows. Max Items then means N new rows. Off by default.

## `stateKey` (type: `string`):

Optional label that separates two monitors of otherwise identical searches (for example one per client). Leave empty to use only the search filters.

## `resetSeen` (type: `boolean`):

Forget what earlier runs of this search returned and start the monitor again from scratch.

## Actor input object example

```json
{
  "recordTypes": [
    "listings"
  ],
  "maxItems": 10,
  "maxItemsPerSearch": 0,
  "operation": "sale",
  "propertyTypes": [],
  "regions": [],
  "districts": [],
  "minPrice": 0,
  "maxPrice": 0,
  "minArea": 0,
  "maxArea": 0,
  "areaBasis": "saleable",
  "bedrooms": [],
  "bathrooms": [],
  "directions": [],
  "floors": [],
  "buildingAge": [],
  "advertisers": [],
  "postedWithinDays": 0,
  "sortBy": "latest",
  "estateKind": "housing",
  "startUrls": [],
  "fetchDetails": true,
  "includeContactDetails": false,
  "maxRunSeconds": 1800,
  "onlyNew": false,
  "stateKey": "",
  "resetSeen": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields per row

## `fullData` (type: `string`):

Complete dataset with all fields

# 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 = {
    "recordTypes": [
        "listings"
    ],
    "maxItems": 10,
    "operation": "sale",
    "startUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("recordsdata/28hse-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 = {
    "recordTypes": ["listings"],
    "maxItems": 10,
    "operation": "sale",
    "startUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("recordsdata/28hse-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "recordTypes": [
    "listings"
  ],
  "maxItems": 10,
  "operation": "sale",
  "startUrls": []
}' |
apify call recordsdata/28hse-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,recordsdata/28hse-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/onLyKWAQAHcSNySOJ/builds/qRQjSAzmGcTY082Do/openapi.json
