# Taiwan Real Estate Actual Price Registration — 實價登錄 API (`chamarix/taiwan-real-estate-transactions`) Actor

Every property deal Taiwan's Ministry of the Interior registers: sales, presale contracts and leases, with price, area, floor, layout, age and parking, normalized to JSON with ping and per-ping prices. All 22 cities, quarterly batches back to 2012.

- **URL**: https://apify.com/chamarix/taiwan-real-estate-transactions.md
- **Developed by:** [chris](https://apify.com/chamarix) (community)
- **Categories:** Real estate, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Taiwan Real Estate Actual Price Registration (實價登錄) API

Get structured JSON access to **every property deal Taiwan's Ministry of the Interior registers** — completed sales, presale contracts and leases — with price, area, floor, layout, building age, parking and the registrar's own notes. All **22 cities and counties**, quarterly batches back to **2012**. Season 115S2 alone holds **75,399 sales, 8,571 presale contracts and 47,610 leases**.

Taiwan has published every registered transaction price since 2012-08-01, which makes it one of the few property markets in the world with a complete, free, official price record. It ships as a 14 MB ZIP of 236 CSVs — one set per city, split three ways, with two header rows, ROC-calendar dates, Chinese numerals for floors and areas in square metres that nobody in Taiwan actually quotes. This Actor turns it into one flat record shape, adds 坪 and per-坪 prices alongside the official ones, and reproduces the Ministry's own unit price from the raw price and areas on every single row as a check that nothing was mis-parsed.

### Why this data matters

- **Actual transaction prices, not asking prices.** Listing sites publish what sellers hope for. This is what the deeds registry recorded, with a statutory 30-day filing deadline behind it.
- **`excludeNoteFlags` is the difference between a price and a market price.** The registrar flags related-party deals, and they are not priced like arm's-length ones: in season 115S2, Taipei's 679 related-party residential deals had a median of **NT$555,980 per ping** against **NT$847,385** for the 3,995 arm's-length ones. Averaging the two together is the most common way to get Taiwan property analysis wrong.
- **`note_flags` splits the registrar's prose into the flags it actually is.** 預售屋、或土地及建物分件登記案件 on 16,393 sales, 其他增建 on 7,033, 陽台外推 on 3,742, 協議價購 on 2,301, 僅車位交易 on 993 — each of which changes how a price should be read.
- **Prices in 坪, which is how the market quotes them.** `unit_price_ping` converts the Ministry's NT$/m² at the exact legal ratio (1 坪 = 400/121 m²). Areas come in both units throughout.
- **The presale book carries the project name.** `project_name` and `building_unit` mean you can follow a single development contract by contract — and `contract_cancelled` catches the rescissions whose prices stay in the register regardless.
- **The lease book separates social housing from market rent.** 27,715 of season 115S2's 47,610 leases are 社會住宅 代管 or 包租轉租, whose rents are set by policy. `rental_service` lets you drop them; `lease_start_date`, `lease_end_date`, `has_furniture` and `equipment` describe what is left.
- **`includeDetails` opens up the parcels behind the deal.** Every land parcel with its number and ownership share, every registered building layer with its own area and age, every parking bay with its price and floor — and each one summed back against the summary row.
- **Nobody serves this in English.** Search for a Taiwan property price API and you find listing scrapers. The official register is free, complete and effectively unusable without a parser.

### Output

One record per registered case. A Da'an District apartment sale:

```json
{
  "record_type": "SALE",
  "record_type_zh": "買賣",
  "source_batch": "115S2",
  "serial_number": "RPVNMLPKNHLGFFA68DA",
  "city": "臺北市",
  "city_code": "a",
  "district": "大安區",
  "address": "臺北市大安區大安路二段２７巷１號五樓之１",
  "property_kind": "房地(土地+建物)",
  "transaction_date": "2026-05-01",
  "transaction_month": "2026-05",
  "transaction_date_roc": "1150501",
  "land_area_sqm": 14.5,
  "land_area_ping": 4.3862,
  "building_area_sqm": 88.38,
  "building_area_ping": 26.7349,
  "urban_land_use": "住",
  "land_count": 1,
  "building_count": 1,
  "parking_count": 0,
  "transaction_counts_raw": "土地1建物1車位0",
  "floor_raw": "五層",
  "floors": [5],
  "floor_tags": [],
  "total_floors": 8,
  "building_type": "華廈(10層含以下有電梯)",
  "main_use": "住家用",
  "main_material": "鋼筋混凝土造",
  "completion_date": "1981-11-02",
  "building_age_years": 44.5,
  "rooms": 4,
  "halls": 2,
  "baths": 2,
  "has_compartment": true,
  "has_management_org": true,
  "total_price": 27000000.0,
  "unit_price_sqm": 305499.0,
  "unit_price_ping": 1009914.05,
  "parking_type": null,
  "parking_price": 0.0,
  "note": "親友、員工、共有人或其他特殊關係間之交易；陽台外推；",
  "note_flags": ["親友、員工、共有人或其他特殊關係間之交易", "陽台外推"],
  "unit_price_check": "MATCH",
  "unit_price_sqm_recomputed": 305498.98,
  "main_building_area_sqm": 66.29,
  "aux_building_area_sqm": 0.0,
  "balcony_area_sqm": 11.51,
  "has_elevator": true,
  "transfer_number": "0026"
}
```

Presale contracts add `project_name`, `building_unit`, `contract_cancelled` and `contract_cancellation_date`. Leases add `lease_kind`, `lease_start_date`, `lease_end_date`, `has_furniture`, `equipment` and `rental_service`. Fields that belong to only one book are `null` on the other two.

With `includeDetails`, each record also carries `details.land`, `details.building` and `details.parking` — the itemised rows behind the summary — plus a `detail_check` saying whether they add up.

### Input

| Field | Type | Notes |
|---|---|---|
| `recordTypes` | array | `SALE`, `PRESALE`, `RENT`. Default `["SALE"]`. Three separate books with different columns. |
| `seasons` | array | ROC quarters, e.g. `["115S2"]`. Empty means the newest published one. Eight per run. |
| `includeLatest` | boolean | Also fetch the ten-day top-up batch published between quarters. |
| `cities` | array | Chinese names, e.g. `["臺北市", "新北市"]`. `台` is accepted for `臺`. Empty means all 22. |
| `districts` | array | e.g. `["大安區"]`. |
| `transactionDateFrom` / `transactionDateTo` | string | `YYYY-MM-DD`. Filters what a season holds; does not choose seasons. |
| `propertyKinds` | array | e.g. `["房地(土地+建物)", "房地(土地+建物)+車位"]` for residential deals without bare land or lone parking bays. |
| `buildingTypes` | array | e.g. `["住宅大樓(11層含以上有電梯)"]`. |
| `minTotalPrice` / `maxTotalPrice` | integer | NTD. For leases this is the monthly rent. |
| `excludeNoteFlags` | array | Drop records whose 備註 contains any of these, e.g. `["親友、員工、共有人或其他特殊關係間之交易"]`. |
| `includeDetails` | boolean | Attach itemised land, building and parking rows, and cross-check their areas. |
| `maxResults` | integer | Default 5000; `0` for everything. A season's sales across all 22 cities is ~75,000 records. |

### How the numbers are verified

The prices and areas are the government's own — this Actor does not compute them. What it does is recompute the government's *derived* number from the government's raw ones, on every row, and report the result per record in `unit_price_check`:

- **The unit price identity, on every row.** The Ministry publishes 單價元平方公尺 but not the rule behind it. Recovering it takes three cases: a land-only deal divides by land area; anything with a building divides by building area after removing the parking bay from both price and area, but only when the bay has a price *and* an area of its own; a deal with no building area falls back to land area. Applied to season 115S2 this reproduces the published figure for **all 129,765 of its 131,580 rows that carry one** — every sale, presale and lease, to within the Ministry's own rounding. The remaining 1,815 rows publish no unit price at all.
- **The order of those cases is not cosmetic.** Eleven land-only rows also carry a building area; dividing those by it lands 20–80% off.
- **Itemised areas summed back against the summary row.** Land, building and parking areas are published twice — once as a total, once itemised in a separate CSV. Across season 115S2's 75,399 sales, **75,271 reconcile**: land and parking areas agree exactly, one building area does not, and 127 are cases where 交易筆棟數 names fewer land parcels than the detail file itemises.
- **Column signatures, per file.** Every column this Actor reads is pinned by name for each of the three books. If the Ministry renames one, the run fails loudly rather than silently filing nulls.
- **Nothing is guessed.** The 22 city letters were each confirmed against the district names inside their own file, over every season from 101S4 to 115S2. A letter outside that set yields `city: null`, not a guess.

### Coverage and limits

- **The register opened on 2012-08-01**, inside season 101S3. The Ministry lists 101S1 and 101S2 as well, but those archives ship no city files at all.
- **A season is cut by registration date, not transaction date.** 115S2 holds sales registered 2026-03-11 to 2026-06-10, whose transactions happened weeks to months earlier — and a handful of which date back decades. Use `transactionDateFrom` / `transactionDateTo` to filter, and expect a transaction to appear in the season *after* the one its date falls in.
- **Leases and presale contracts run on their own windows.** The same 115S2 archive holds leases contracted 2026-02-11 to 2026-05-10 and presale transactions over the same span. Each run logs the exact window the Ministry printed.
- **Street numbers are masked to a range on residential cases.** That is the Ministry's privacy rule, not a parsing loss. Land-only cases carry the parcel instead.
- **`building_age_years` is null for presale units**, which transact before the building exists, and for the roughly one sale in four where the register leaves the completion date blank. About one sale in six hundred carries a completion date whose day is out of range or unreadable; those keep `completion_month` where they can and drop `completion_date`.
- **`floors` and `floor_tags` split a field that is not always a number.** One case can name several floors at once and mix them with 全, 騎樓, 陽台, 夾層 or 見其他登記事項. Numbered floors go in `floors` with basements negative; everything else is kept verbatim in `floor_tags` rather than dropped.
- **The ten-day increment overlaps nothing and repeats little.** Combined with a season it can restate a record; de-duplicate on `serial_number`, which is unique within a batch.
- **`maxResults` cuts city by city, in the Ministry's order.** A low limit returns whole cities rather than a sample across all of them. Set `0` for everything.

### Taiwan Market Data Suite

This Actor is part of a suite of 23 Taiwan market data APIs by [chamarix](https://apify.com/chamarix) — official sources only, cross-validated against independent official endpoints, clean JSON out. Code samples for the whole suite: [GitHub](https://github.com/cc77556/taiwan-market-data-actors).

**Market data:**

- [twse-institutional-trades](https://apify.com/chamarix/twse-institutional-trades) — Daily institutional buy/sell (foreign, investment trust, dealer) per stock — TWSE listed
- [tpex-institutional-trades](https://apify.com/chamarix/tpex-institutional-trades) — Daily institutional buy/sell per stock — TPEx OTC market
- [taiwan-monthly-revenue](https://apify.com/chamarix/taiwan-monthly-revenue) — Monthly revenue of 1,900+ listed & OTC companies, MoM/YoY
- [taiwan-financial-statements](https://apify.com/chamarix/taiwan-financial-statements) — Quarterly income statement, balance sheet & cash flow back to 2013
- [taiwan-dividend-calendar](https://apify.com/chamarix/taiwan-dividend-calendar) — Ex-dividend / ex-rights dates, reference prices & payouts back to 2003
- [taiwan-margin-trading](https://apify.com/chamarix/taiwan-margin-trading) — Daily margin trading & short sale balances per stock
- [taiwan-sbl-short-sale-balance](https://apify.com/chamarix/taiwan-sbl-short-sale-balance) — Securities-lending short sale balances per stock
- [taiwan-day-trading-stats](https://apify.com/chamarix/taiwan-day-trading-stats) — Day-trading volume, value & ratio per stock since 2014
- [tdcc-shareholding-dispersion](https://apify.com/chamarix/tdcc-shareholding-dispersion) — Weekly TDCC shareholding dispersion (retail vs whale structure)
- [taiwan-foreign-shareholding](https://apify.com/chamarix/taiwan-foreign-shareholding) — Foreign ownership percentage & remaining quota per stock
- [taifex-institutional-derivatives](https://apify.com/chamarix/taifex-institutional-derivatives) — Institutional futures & options positions (TAIFEX), incl. put/call ratio
- [taiwan-warrants-daily](https://apify.com/chamarix/taiwan-warrants-daily) — Daily quotes, strike, expiry & moneyness for every listed/OTC warrant since 2004
- [taiwan-stock-alerts](https://apify.com/chamarix/taiwan-stock-alerts) — Watch-list, disposition & short-sale suspension alerts
- [taiwan-insider-share-transfers](https://apify.com/chamarix/taiwan-insider-share-transfers) — Insider share-transfer filings (directors, officers, 10% holders) since 2002
- [taiwan-director-shareholdings](https://apify.com/chamarix/taiwan-director-shareholdings) — Monthly director/officer shareholdings & share-pledge ratio since 1999
- [taiwan-block-trades](https://apify.com/chamarix/taiwan-block-trades) — Every block trade (鉅額交易) with price, size & basket constituents since 2005
- [taiwan-shareholder-meetings](https://apify.com/chamarix/taiwan-shareholder-meetings) — Shareholder meeting dates, book closure periods & e-voting since 2005
- [taiwan-emerging-stock-quotes](https://apify.com/chamarix/taiwan-emerging-stock-quotes) — Emerging (興櫃) board quotes, pre-IPO register & history since 2003
- [taiwan-etf-regular-investment](https://apify.com/chamarix/taiwan-etf-regular-investment) — Monthly regular savings plan (定期定額) rankings for stocks & ETFs since 2020
- [taiwan-treasury-stock-buybacks](https://apify.com/chamarix/taiwan-treasury-stock-buybacks) — Every treasury-stock buyback (庫藏股) filing, plan vs execution, since 2000

**Property market:**

- [taiwan-real-estate-transactions](https://apify.com/chamarix/taiwan-real-estate-transactions) — Actual registered sale, presale & lease prices (實價登錄) for all 22 cities since 2012

**Government & civic data:**

- [taiwan-legislator-monitor](https://apify.com/chamarix/taiwan-legislator-monitor) — Legislative Yuan bills, legislators & meetings
- [taiwan-tender-monitor](https://apify.com/chamarix/taiwan-tender-monitor) — Government e-procurement tenders (open calls, awards, failures)

### Data source

Ministry of the Interior 不動產交易實價查詢服務網 (plvr.land.moi.gov.tw) — the quarterly 不動產成交案件實際資訊資料 archives and the ten-day increment. Public open data, no login and no API key required.

# Actor input Schema

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

The register is published as three separate books and they do not share columns. SALE is completed transfers of land and buildings, PRESALE is contracts on units that are not built yet (with the project's name attached), RENT is leases (with the term, furnishings and equipment attached). Season 115S2 held 75,399 sales, 8,571 presale contracts and 47,610 leases.

## `seasons` (type: `array`):

Quarterly batches to download, written the Ministry's way: 115S2 is the second quarter of ROC year 115, i.e. 2026. A season is cut by registration date, not transaction date — 115S2 holds sales registered 2026-03-11 to 2026-06-10, whose transactions happened weeks to months earlier. Leave empty for the newest published season. The register opened on 2012-08-01, inside 101S3; eight seasons is the per-run ceiling.

## `includeLatest` (type: `boolean`):

The Ministry publishes a small top-up batch three times a month, ahead of the quarterly archive. Turn this on to add the registrations made since the last quarter closed — around 2 MB against a season's 14 MB. Combined with a season it can repeat a record, so de-duplicate on serial\_number.

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

Chinese names, e.g. \['臺北市', '新北市']. 台 is accepted in place of 臺. Leave empty for all 22. Each city is a separate file inside the archive, so narrowing this genuinely saves work.

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

Keep only these 鄉鎮市區, e.g. \['大安區', '信義區']. Matched exactly against the Ministry's own spelling.

## `transactionDateFrom` (type: `string`):

Keep only records transacted on or after this date. This filters what a season contains; it does not choose which seasons to download. A season's transactions cluster in the two to three months before its registration window, and a few reach back decades.

## `transactionDateTo` (type: `string`):

Keep only records transacted on or before this date, inclusive.

## `propertyKinds` (type: `array`):

Keep only these 交易標的. Sales and presale contracts use 房地(土地+建物)+車位, 房地(土地+建物), 土地, 車位 and 建物 — in season 115S2's sales they ran 30,957 / 26,251 / 16,727 / 1,036 / 428, so filtering to the two 房地 kinds is the usual way to get residential deals without bare land and lone parking bays. Leases use a different set: 租賃房屋, 租賃房屋+車位, 土地, 車位.

## `buildingTypes` (type: `array`):

Keep only these 建物型態: 住宅大樓(11層含以上有電梯), 華廈(10層含以下有電梯), 公寓(5樓含以下無電梯), 透天厝, 套房(1房1廳1衛), 廠辦, 辦公商業大樓, 店面(店鋪), 工廠, 倉庫, 農舍, 其他.

## `minTotalPrice` (type: `integer`):

Keep only records at or above this total price. For leases this is the monthly rent, which is a different order of magnitude.

## `maxTotalPrice` (type: `integer`):

Keep only records at or below this total price.

## `excludeNoteFlags` (type: `array`):

Drop any record whose 備註 contains one of these phrases. The registrar picks most notes from a standard list, so this is the practical way to strip prices that are not market prices: \['親友、員工、共有人或其他特殊關係間之交易'] removes related-party deals, and in season 115S2 those 679 Taipei residential deals had a median of NT$555,980 per ping against NT$847,385 for the 3,995 arm's-length ones. Other useful ones are 僅車位交易, 協議價購 and 政府機關標讓售.

## `includeDetails` (type: `boolean`):

Attach the register's detail files: every land parcel with its number and ownership share, every registered building layer with its own age and area, and every parking bay with its price and floor. It also turns on a cross-check — the itemised areas are summed and compared against the summary row, and the result is reported per record in detail\_check. Records get noticeably larger.

## `maxResults` (type: `integer`):

Stop after this many records. A single season's sales across all 22 cities is about 75,000 records, so the default keeps an exploratory run small. Set 0 for no limit. Records are read city by city in the Ministry's own order, so a low limit returns whole cities rather than a sample of all of them.

## Actor input object example

```json
{
  "recordTypes": [
    "SALE"
  ],
  "seasons": [
    "115S2"
  ],
  "includeLatest": false,
  "cities": [
    "臺北市"
  ],
  "districts": [],
  "transactionDateFrom": "",
  "transactionDateTo": "",
  "propertyKinds": [],
  "buildingTypes": [],
  "excludeNoteFlags": [],
  "includeDetails": false,
  "maxResults": 5000
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

One record per registered case — price, area in both m² and ping, floor, layout, building age and parking — with the Ministry's own unit price checked against the price and areas on the same row.

# 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": [
        "SALE"
    ],
    "seasons": [
        "115S2"
    ],
    "cities": [
        "臺北市"
    ],
    "districts": [],
    "transactionDateFrom": "",
    "transactionDateTo": "",
    "propertyKinds": [],
    "buildingTypes": [],
    "excludeNoteFlags": [],
    "maxResults": 5000
};

// Run the Actor and wait for it to finish
const run = await client.actor("chamarix/taiwan-real-estate-transactions").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": ["SALE"],
    "seasons": ["115S2"],
    "cities": ["臺北市"],
    "districts": [],
    "transactionDateFrom": "",
    "transactionDateTo": "",
    "propertyKinds": [],
    "buildingTypes": [],
    "excludeNoteFlags": [],
    "maxResults": 5000,
}

# Run the Actor and wait for it to finish
run = client.actor("chamarix/taiwan-real-estate-transactions").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": [
    "SALE"
  ],
  "seasons": [
    "115S2"
  ],
  "cities": [
    "臺北市"
  ],
  "districts": [],
  "transactionDateFrom": "",
  "transactionDateTo": "",
  "propertyKinds": [],
  "buildingTypes": [],
  "excludeNoteFlags": [],
  "maxResults": 5000
}' |
apify call chamarix/taiwan-real-estate-transactions --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chamarix/taiwan-real-estate-transactions"
        }
    }
}

```

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/fqRWxkhRQAHAeoaBV/builds/QEikPtNMZHlfMeZeo/openapi.json
