**Source (original):** Ministry of Land, Infrastructure and Transport (MOLIT), published through Korea’s open data portal data.go.kr. Free, “이용허락범위 제한 없음” (no restriction on use, commercial included), auto-approved API key, 10,000 calls/day on a dev account.
– Apartment sales: https://www.data.go.kr/data/15126469/openapi.do
– Apartment rent (jeonse/wolse): https://www.data.go.kr/data/15126474/openapi.do
– Officetel, commercial/office buildings, row houses, land etc. are separate endpoints under the same publisher.
**What’s in it.** Every registered transaction, by district (5-digit LAWD_CD) and month. Sales give price, exclusive area, floor, build year, road address, and a cancellation flag. Leases give deposit, monthly rent, previous deposit/rent, contract term, whether the renewal right was exercised. Unit/door numbers are withheld for privacy, so there’s no PII in it. History goes back years; my checks were on 2026.
**Gotchas** (all of these cost me time):
-
XML only, no JSON.
-
Two generations of endpoints coexist. Legacy ones return Korean tag names (`거래금액`, `전용면적`), the `*Dev` ones return English (`dealAmount`, `excluUseAr`). Same data, different keys.
-
Tag casing is inconsistent *between* endpoints: sales give `roadNm` / `roadNmBonbun`, rent gives `roadnm` / `roadnmbonbun`. Bit me directly. (Sales is also internally inconsistent: `roadNmCd` but `roadNmbCd`.)
-
Amounts are in 만원 (10,000 KRW) as comma-formatted strings, sometimes padded — `’38,670’` means 386,700,000 KRW. Parse, don’t cast.
-
The commercial-property endpoint has no exclusive-area field at all, only building area. Don’t assume the schema generalizes.
-
Service keys come in encoded and decoded flavors; double-encoding the encoded one silently returns `SERVICE_KEY_IS_NOT_REGISTERED_ERROR`, which reads like an auth problem but isn’t.
-
You must file a separate usage application per API, not once per account.
**The gotcha worth the post: don’t pool 신규 (new) and 갱신 (renewal) lease contracts.**
Renewals are capped at +5% by Korea’s lease cap law, so they sit below market. The API labels them in `contractType`, and if you ignore that label, you’re publishing a number that’s a blend of market prices and legally-capped ones.
Seoul, all 25 districts, July 2026, apartment leases (n = 16,520; 8,310 new / 7,896 renewal / 314 unlabeled):
| | all contracts | new only |
|—|—|—|
| jeonse share | 50.2% | **43.9%** |
| median jeonse deposit | 570M KRW | **598M KRW** |
| median monthly rent (wolse) | 730k KRW | **800k KRW** |
So “Seoul is half jeonse” is an artifact of pooling — renewals skew jeonse-heavy because that’s who exercises the renewal right. New-contract share is 44% and falling.
New contracts only, by district, July 2026:
| District | n | jeonse % | median jeonse deposit | median wolse rent | median wolse deposit |
|—|—|—|—|—|—|
| Gangnam | 575 | 41% | 900M | 1.60M | 200M |
| Seocho | 521 | 47% | 850M | 1.71M | 281M |
| Gwangjin | 153 | 38% | 775M | 0.77M | 138M |
| Songpa | 649 | 53% | 770M | 1.50M | 240M |
| Yongsan | 198 | 36% | 750M | 1.55M | 173M |
| Dongjak | 254 | 47% | 750M | 1.42M | 200M |
| Seongdong | 285 | 52% | 710M | 1.95M | 150M |
| Jung | 145 | 37% | 700M | 1.10M | 50M |
| Mapo | 385 | 46% | 690M | 1.60M | 100M |
| Seongbuk | 265 | 45% | 650M | 0.80M | 112M |
| Seodaemun | 246 | 48% | 650M | 0.90M | 100M |
| Yeongdeungpo | 395 | 41% | 630M | 0.70M | 129M |
| Jongno | 94 | 29% | 600M | 0.60M | 50M |
| Gangdong | 523 | 38% | 600M | 0.60M | 101M |
| Yangcheon | 387 | 56% | 550M | 0.60M | 99M |
| Gwanak | 292 | 32% | 545M | 0.70M | 71M |
| Gangseo | 414 | 50% | 480M | 0.70M | 100M |
| Jungnang | 365 | 20% | 460M | 0.44M | 94M |
| Eunpyeong | 395 | 50% | 450M | 0.50M | 102M |
| Dongdaemun | 457 | 36% | 450M | 0.54M | 88M |
| Guro | 297 | 43% | 438M | 0.60M | 58M |
| Geumcheon | 129 | 35% | 380M | 0.55M | 60M |
| Dobong | 197 | 55% | 370M | 0.75M | 50M |
| Nowon | 579 | 49% | 340M | 0.80M | 40M |
| Gangbuk | 110 | 46% | 314M | 0.76M | 30M |
| **Seoul** | **8,310** | **44%** | **598M** | **0.80M** | **100M** |
All figures are medians in KRW, straight from the API, no adjustment. Jeonse is a deposit-only lease (no monthly rent); wolse is deposit + monthly rent, so the two deposit columns aren’t comparable.
**Disclosure — I built a free wrapper.** Getting from the raw XML to the table above is annoying enough that I published four Apify actors that normalize it: English field names, integer KRW instead of 만원 strings, per-m²/per-pyeong unit price, ISO dates, an `isJeonse` flag, unknown tags passed through rather than dropped. They’re free and need no API key of your own.
– https://apify.com/ootssu/korea-apartment-transaction-prices
– https://apify.com/ootssu/korea-apartment-rent-prices
– https://apify.com/ootssu/korea-officetel-prices
– https://apify.com/ootssu/korea-commercial-property-prices
The source of truth is MOLIT, not me — if you’d rather hit data.go.kr yourself, the links up top are all you need, and the gotcha list should save you the afternoon it cost me.
submitted by /u/porche911_kr
[link] [comments]