# Korea 아파트 실거래가 API (Korea Apartment Transactions) (`linus009400/korea-apartment-transactions-scraper`) Actor

Every apartment sale in Korea from the government register, in real KRW. The raw API quotes 만원, so 145,000 means 1,450,000,000 won. Fixed here, plus price per m² and per pyeong, English district names, and cancelled contracts flagged so they don't inflate your averages.

- **URL**: https://apify.com/linus009400/korea-apartment-transactions-scraper.md
- **Developed by:** [HEESEOK HONG](https://apify.com/linus009400) (community)
- **Categories:** Real estate, Lead generation, Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 transaction records

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

## Korea Apartment Sale Transactions Scraper

**Every apartment sale in Korea, from the government register — with prices in real won and districts in English.**

Korea publishes every apartment sale contract. Price, date, exact building, floor, exclusive area, whether it went through an agent, whether the buyer was a company. It is one of the most complete residential price datasets any country makes public.

It is also, in raw form, a trap.

```xml
<dealAmount>145,000</dealAmount>
```

That is not ₩145,000. The unit is 만원 — ten thousand won — so the real figure is **₩1,450,000,000**. About 1.45 billion won. Anyone reading the raw field is wrong by a factor of ten thousand, and nothing in the response says so.

This actor fixes that and everything else in the way.

***

### What you get

```json
{
  "dealDate": "2026-06-20",
  "sidoEn": "Seoul",
  "sggEn": "Gangnam-gu",
  "sggKr": "강남구",
  "umdKr": "수서동",
  "aptName": "까치마을",
  "floor": 6,
  "buildYear": 1993,
  "areaSqm": 34.44,
  "areaPyeong": 10.42,
  "areaSqft": 370.7,
  "priceKrw": 1450000000,
  "priceManwon": 145000,
  "priceKrwPerSqm": 42102207,
  "priceKrwPerPyeong": 139180843,
  "currency": "KRW",
  "buyerType": "INDIVIDUAL",
  "sellerType": "INDIVIDUAL",
  "dealChannel": "THROUGH_AGENT",
  "isCancelled": false,
  "isLandLease": false
}
```

Against the raw API, this actor:

- **Converts 만원 to real KRW** — and keeps `priceManwon` and the original string so you can audit it
- **Adds price per m² and per pyeong**, computed before rounding so the figures don't drift
- **Gives area three ways** — m² as filed, 평 because that is how Koreans quote it, ft² because you may not
- **Assembles one date** from the three separate year / month / day fields
- **Translates the Korean enum values** — 개인 → `INDIVIDUAL`, 법인 → `CORPORATION`, 중개거래 → `THROUGH_AGENT`, 직거래 → `DIRECT`
- **Resolves districts by name** — you pass `Gangnam-gu`, not `11680`
- **Flags cancelled contracts.** Korea records contracts and then records their withdrawal. Leaving those in inflates apparent market prices, so they are excluded unless you ask for them
- **Flags land-lease apartments** (`토지임대부`), which trade far below freehold units and will skew any average that mixes them in
- **Returns `null` for genuinely blank fields.** The raw API sends a single space character, which silently survives most parsers as a truthy value

***

### Who uses this

- **Property analytics and proptech** — a normalised national price feed without building the plumbing
- **Funds and research desks** — Korean housing as a macro signal, in a form you can regress on
- **Relocation and expat services** — real prices for a specific building, in English
- **Appraisal and lending** — comparable sales for a district and unit size
- **Journalists and researchers** — official figures with the traps removed
- **AI agents** — available through Apify's MCP server as a tool call

***

### How to use it

Press **Run**. The defaults pull last month's sales in Gangnam-gu.

| Input | What it does |
|---|---|
| `regions` | `Gangnam-gu`, `강남구`, `서울 강남구`, or `11680`. Mix freely. |
| `monthFrom` / `monthTo` | `2026-01` to `2026-06`. Leave empty for the last completed month. |
| `months` | Exact months, e.g. `2025-06` and `2026-06` for a year-on-year read. |
| `minPriceKrw` / `maxPriceKrw` | In actual won. One billion is `1000000000`. |
| `minAreaSqm` / `maxAreaSqm` | 84 m² is the standard Korean family unit. |
| `includeCancelled` | Off by default, for the reason above. |
| `maxResults` | Hard cap on billed rows. |

#### Districts

334 queryable districts, covering the whole country. All 25 Seoul districts and the major Gyeonggi and metropolitan districts have English names; the rest resolve by Korean name or code.

Cities divided into 구 must be queried at 구 level — the register has no city-wide figure. Ask for `Seongnam Bundang-gu`, not `성남시`. If a name is ambiguous (`중구` exists in eight provinces) the actor returns the candidate codes rather than guessing.

The lookup table is generated from the Ministry of the Interior's 법정동코드 register and pruned of everything that cannot be queried: abolished districts, renamed ones like 인천 남구 → 미추홀구, 출장소 entries, and parent cities superseded by their 구.

#### Coverage and timing

Transactions are filed after the contract is signed, so the current month is always thin and fills in over the following weeks. For a settled picture, read months that are at least 30 days old.

Volume varies enormously by district — a busy Seoul district produces 200–400 sales a month, a rural county may produce none. An empty result for a small district usually means there were no sales, not that something broke.

#### API keys

Works out of the box on a shared key. For scheduled or high-volume runs, get your own — free, approved automatically, about two minutes at [data.go.kr](https://www.data.go.kr/data/15126469/openapi.do). Use the **Decoding** key; the Encoding one is pre-escaped and will fail. Each key allows 10,000 requests per day.

***

### Output

Results go to the default dataset — export as JSON, CSV, Excel or XML, or pull them through the Apify API. A `RUN_SUMMARY` record records rows returned, API calls used, how many rows the filters removed, and any districts that could not be resolved, so a scheduled run tells you exactly what happened.

### Legality

This actor reads the Ministry of Land, Infrastructure and Transport's official open API, published through data.go.kr for exactly this purpose. No page scraping, no authentication bypass, no personal data — the register identifies buildings and lots, never people.

***

Built by a fintech CTO. Found a bug, or want 전월세 (rent) or non-apartment property types added? Open an issue on the **Issues** tab — I read them.

# Actor input Schema

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

English name (`Gangnam-gu`), Korean name (`강남구`, `서울 강남구`), or a 5-digit 시군구 code (`11680`). Mix freely. Cities that are divided into 구 must be given at 구 level — `Seongnam Bundang-gu`, not `성남시`.

## `monthFrom` (type: `string`):

`YYYY-MM`, e.g. `2026-01`. Defaults to the last completed month — the current month is usually still incomplete because filings lag the contract date.

## `monthTo` (type: `string`):

`YYYY-MM`. Leave empty to fetch a single month.

## `months` (type: `array`):

Exact months to fetch, e.g. `2025-06`, `2026-06`. Overrides the range above — useful for year-on-year comparisons.

## `minPriceKrw` (type: `integer`):

In actual won, not 만원. One billion won is `1000000000`.

## `maxPriceKrw` (type: `integer`):

In actual won, not 만원.

## `minAreaSqm` (type: `integer`):

Exclusive-use area. 84 m² is the standard Korean family unit, roughly 25 pyeong.

## `maxAreaSqm` (type: `integer`):

Exclusive-use area in square metres.

## `includeCancelled` (type: `boolean`):

Off by default. Cancelled contracts are reported to the register and then withdrawn — leaving them in inflates apparent market prices.

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

Hard cap on billed rows. A busy Seoul district produces 200-400 sales per month.

## `serviceKey` (type: `string`):

Leave empty to use the shared key. For scheduled or high-volume runs get your own — it is free and approved automatically at [data.go.kr](https://www.data.go.kr/data/15126469/openapi.do). Use the **Decoding** key. Each key allows 10,000 requests per day.

## Actor input object example

```json
{
  "regions": [
    "Gangnam-gu",
    "Songpa-gu",
    "Seongnam Bundang-gu"
  ],
  "includeCancelled": false,
  "maxResults": 1000
}
```

# 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 = {
    "regions": [
        "Gangnam-gu",
        "Songpa-gu",
        "Seongnam Bundang-gu"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("linus009400/korea-apartment-transactions-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 = { "regions": [
        "Gangnam-gu",
        "Songpa-gu",
        "Seongnam Bundang-gu",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("linus009400/korea-apartment-transactions-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 '{
  "regions": [
    "Gangnam-gu",
    "Songpa-gu",
    "Seongnam Bundang-gu"
  ]
}' |
apify call linus009400/korea-apartment-transactions-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,linus009400/korea-apartment-transactions-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/QRRPSynkkmMAKnl5e/builds/vank9EThzBeNlLLbo/openapi.json
