Midland Realty Scraper – HK Listings & Transactions (No API) avatar

Midland Realty Scraper – HK Listings & Transactions (No API)

Pricing

from $2.00 / 1,000 listing / transaction / estates

Go to Apify Store
Midland Realty Scraper – HK Listings & Transactions (No API)

Midland Realty Scraper – HK Listings & Transactions (No API)

Scrape Midland Realty Hong Kong without an API: 44K for-sale and for-rent listings, 1.8M historical transactions and 18K estates. Price, rent, saleable area, price per sq ft, bedrooms, school net and coordinates as JSON/CSV/Excel — for HK property research and agency inventory comparison.

Pricing

from $2.00 / 1,000 listing / transaction / estates

Rating

0.0

(0)

Developer

Chad

Chad

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

5 days ago

Last modified

Security

Limited permissions

Share

Midland Realty Scraper (Hong Kong)

Scrape Midland Realty's public Hong Kong property data with one Actor: listings for sale and rent, historical transaction records, and the full estate directory. Public JSON API — no login, no API key, no browser.

Midland has the largest branch network of any Hong Kong estate agency, and the dataset is a tier larger than most comparable sources:

ModeRows available
Listings44,190 (31,530 for sale / 15,563 for rent)
Transactions1,855,568
Estates17,964

Output fields

Listings (mode: search)

FieldTypeDescription
serial_nostringMidland listing number, e.g. M351962478
deal_typestringbuy or rent
regionstring|nullHong Kong Island / Kowloon / New Territories
subregionstring|nullSub-region, e.g. Tsuen Wan
districtstring|nullDistrict, e.g. Ma Wan
sm_districtstring|nullSmaller district subdivision
estate / estate_idstring|nullEstate name and Midland estate ID
phasestring|nullPhase, e.g. Phase 1
building / building_idstring|nullBuilding name and ID
price_hkdnumber|nullAsking price in HKD. null for rentals
rent_hkdnumber|nullMonthly rent in HKD. null for sale listings
net_area_sqftnumber|nullSaleable area in square feet
gross_area_sqftnumber|nullGross area in square feet
net_to_gross_rationumber|nullEfficiency ratio (%)
net_unit_price_hkdnumber|nullSale price per saleable square foot (HKD). null for rentals
net_unit_rent_hkdnumber|nullMonthly rent per saleable square foot (HKD). null for sales
monthly_mortgage_hkdnumber|nullMidland's estimated monthly mortgage payment
bedroom / sitting_roomnumber|nullBedroom / living room count
orientationstring|nullFacing direction
primary_school_netnumber|nullPrimary school net number
has_video / has_photo_360boolean|nullWhether a video / 360° photo exists
tagsstring[]|nullListing tags, e.g. sole (sole agency)
agent_name_zh / agent_name_enstring|nullAgent name
latitude / longitudenumber|nullCoordinates
photo_urlsstring[]|nullPhoto URLs
listing_urlstring|nullMidland listing page
updated_atstring|nullListing update time (ISO 8601)
scraped_atstringScrape time (ISO 8601)

Transactions (mode: transactions)

transaction_id, region / subregion / district, estate / estate_id, building, floor, flat, price_hkd, net_area_sqft, gross_area_sqft, net_unit_price_hkd, transaction_date, transaction_type, source (e.g. LANDREG for Land Registry), tags, latitude / longitude, transaction_url, updated_at, scraped_at

Estates (mode: estates)

estate_id, name, region / subregion / district / sm_district, first_op_date (occupation date), total_unit_count, total_block_count, primary_school_net, sale_listing_count / rent_listing_count, net_unit_price_hkd (recent price per saleable sq ft), recent_transaction_count, amenities (nearby facilities with walking minutes), latitude / longitude, photo_url, estate_url, scraped_at

Field names are always English snake_case. Missing values are always null — fields are never omitted, so the output drops straight into a table.

Modes

ModeWhat you getTypical use
searchListings for sale / rentCross-agency inventory comparison, sourcing, price monitoring
transactionsHistorical sales recordsBuilding your own price index, valuation models, trend analysis
estatesEstate directory and statsEstate reference database, supply analysis

Input

FieldTypeDefaultDescription
modeenumsearchsearch / transactions / estates
dealTypeenumbuybuy or rent (ignored in Estates mode)
regionsstring[]allHong Kong Island / Kowloon / New Territories; empty = all three
bulkRegionsstring—One per line, merged with the field above
bedroomsinteger—Exactly N bedrooms
bathroomsinteger—Exactly N bathrooms
schoolNetinteger—Specific primary school net
sortenumdefaultNewest / price / saleable area / price per sq ft, ascending or descending
languageenumenLanguage of region and estate names (field names stay English)
maxItemsinteger50Max rows for this run, max 500
onlyNewbooleanfalseOnly return items not returned by earlier runs (monitoring); see below
stateKeystringautoName of the remembered state; empty = derived from mode + filters
proxyConfigurationobjectresidentialKeep the default — see Notes

Input examples

1. 100 Kowloon listings for sale

{ "mode": "search", "dealType": "buy", "regions": ["Kowloon"], "maxItems": 100 }

2. Three-bedroom listings across Hong Kong, cheapest price per sq ft first

{ "mode": "search", "dealType": "buy", "bedrooms": 3, "sort": "net_ft_price", "maxItems": 200 }

3. Hong Kong Island rentals with Chinese estate names

{ "mode": "search", "dealType": "rent", "regions": ["Hong Kong Island"], "language": "zh-hk", "maxItems": 50 }

4. New Territories transaction records

{ "mode": "transactions", "dealType": "buy", "regions": ["New Territories"], "maxItems": 300 }

5. Full estate directory

{ "mode": "estates", "maxItems": 500 }

Use it from Claude or any AI agent (MCP)

This actor is already available as a tool through Apify's official hosted MCP server — nothing extra to install, and billing is identical to a normal run (per item, no MCP surcharge).

Add it to Claude Code in one line (get $APIFY_TOKEN from Apify Console → Settings → API & Integrations):

$claude mcp add --transport http apify "https://mcp.apify.com/?tools=claude_code_reviewer/midland-scraper-en" --header "Authorization: Bearer $APIFY_TOKEN"

Claude Desktop, Cursor and other MCP clients: add https://mcp.apify.com as a custom connector and sign in with OAuth.

Midland only filters by region — it does not accept estate names or keywords (the official API silently ignores them), so have the agent filter the estate field after fetching. Then just ask:

Use the Midland scraper (language: en) to fetch the latest 500 New Territories transactions, then keep only rows whose estate field contains "City One" and compute the median saleable price per sq ft.

The agent first receives a summary and a dataset id, then reads the rows with get-dataset-items (you can request only the fields you need to save tokens).

Don't want to set this up? See the managed option below.

Only new items (monitoring)

Default behaviour is unchanged: every run returns the full result. With onlyNew on, the actor remembers the items it already returned in a key-value store named delta-state-<actor ID> (one per actor) in your account, and later runs with the same input output only newly seen items; already-seen items are skipped and not charged. The first run behaves like a normal run and seeds the memory. When nothing is new the run still succeeds (the log says "No new items").

Scheduling example (same input every day, get only new listings):

{ "mode": "search", "dealType": "buy", "regions": ["Kowloon"], "sort": "latest", "onlyNew": true, "maxItems": 200 }
  • stateKey: when empty it is derived from the fields that define what is scraped (mode, deal type, regions, filters, sort; maxItems, proxy and language do not matter), so the same scheduled input continues where it left off. To keep separate memories for different schedules or integrations, set your own name (letters, digits, _, -, 1-100 chars). Most API callers reuse inputs, so setting it explicitly is recommended.
  • Identity: search uses serial_no, transactions uses transaction_id, estates uses estate_id (kept separate per mode). In estates mode only newly appearing estates are returned.
  • Sorting: any sort works, but for monitoring sort: "latest" is the efficient choice. With other sorts the actor keeps paging through already-seen pages and stops after 5 such pages in a row, so new listings further down can still be found, at the cost of more requests.
  • Each state key remembers the latest 20,000 items; maxItems counts new items only.

Notes

  • Keep the proxy default (Apify residential). Midland returns 403 to datacenter egress — even the page that issues the access token is blocked. Turning the proxy off or switching it to datacenter yields zero rows. JSON responses are about 4KB per row, so residential traffic cost is negligible.
  • The only filters that actually work are regions, bedrooms, bathrooms and schoolNet. Midland's public API silently ignores estate-name, sub-district, price-range and area-range filters — sending them changes nothing in the response. This Actor deliberately does not send them, so you are never misled into thinking a filter applied. To filter by estate or price, filter the output yourself.
  • maxItems is the total across all regions, not per region.
  • 2026-11-02 field fix: for listings, net_unit_price_hkd used to read the rent-per-square-foot value, so it was almost always null for sales and held the rent per square foot for rentals. It now holds the sale price per saleable square foot (sales only), and rent per square foot has moved to the new net_unit_rent_hkd field. If you used net_unit_price_hkd on rentals as rent per square foot, read net_unit_rent_hkd instead.
  • rent_hkd is null on sale listings and price_hkd is null on rentals. Midland reports 0 in those fields; we normalise 0 to null so you never see a "HK$0" property.
  • If new listings appear while scraping, pages shift and rows can repeat. This Actor de-duplicates across the whole run, so each row is output — and charged — only once.
  • Public data only. No login, no authentication bypass.
  • Usage terms: only public listing data from Midland's website is collected. Respect Midland's terms of use and do not reproduce or redistribute site content.
  • Personal data: if the output includes agent names or phone numbers, you must comply with Hong Kong's Personal Data (Privacy) Ordinance (PDPO) and must not use them for unsolicited marketing.
  • The Actor keeps a low request rate (at most 3 concurrent requests per run) to avoid burdening the site.

Pricing

A single event, search-listing, at $0.002 per row output (same in all three modes). Only rows successfully written to the dataset are charged; duplicates and filtered-out rows are not.

FAQ

Q: Can I scrape a single estate, e.g. Taikoo Shing? A: Not directly — Midland's public API has no estate or keyword filter (we tested keyword, keywords, estate_id, q and others; all are ignored or break the response). Use estates mode to pull the estate directory, or scrape the region and filter on the estate field.

Q: How far back do the transaction records go? A: The database holds 1.86 million records, sourced from Land Registry filings (source: LANDREG) among others. Currently they can be paged by region and sale/rent only — there is no date-range parameter.

Q: What's the difference between net_area_sqft and gross_area_sqft? A: net_area is saleable area and area is gross area; net_to_gross_ratio is the efficiency ratio. Hong Kong has required saleable-area disclosure since 2013, so prefer net_area_sqft. Some listings have no gross area, in which case the field is null.

Q: Can I merge this with Centaline data? A: Yes — that's a primary use case. Both output snake_case fields, region hierarchies and estate names, which suits agency-vs-agency inventory and pricing comparison. Estate naming differs slightly between sites, so fuzzy-match on district plus estate name.

Q: Why does it need a residential proxy? Is that expensive? A: Midland blocks datacenter IPs, so without residential you get no data at all. The API is very compact (about 4KB per row), so measured traffic cost is far below the per-row price.

Q: I got fewer rows than maxItems. A: That filter combination is exhausted. Loosen the filters (drop bedrooms, say) or scrape another region.

Q: With Only new items on, why did my run return 0 rows? A: Nothing new appeared since the last run with the same state key. That is a normal result (the run succeeds and nothing is charged). To get everything again, use a different stateKey or turn onlyNew off.

Disclaimer

This Actor is intended for lawful purposes only, such as personal research, academic analysis, market research and property trend studies. Please comply with Midland Realty's (midland.com.hk) terms of service and applicable Hong Kong law. Do not scrape at excessive volume and do not resell raw data. The author accepts no liability for any damage arising from use of this tool.


Hong Kong property scraper Midland Realty scraper HK real estate data property listings transaction records estate directory saleable area price per square foot Hong Kong estate agency property data export HK housing market research valuation model


Hands-on guides and free tools built on this actor, at AI Social API:

Maintained by an operator running 30+ live Apify actors.