Dokumentasi
Gambaran umum
Indonesia Region API menerbitkan kode dan nama wilayah administrasi pemerintahan Indonesia sebagai file JSON statis. Tidak ada server, database, maupun API key: setiap endpoint adalah file di CDN, sehingga bisa dipakai oleh klien HTTP apa pun dalam bahasa pemrograman apa pun.
- Base URL:
https://indonesia-region.caturseptian.site/api/v1/(atau/api/v1/di salinan yang di-host sendiri). - Hanya-baca, hanya
GET, tanpa autentikasi. - JSON UTF-8, urutan deterministik (berdasarkan kode), tanpa timestamp build.
- Dataset saat ini:
kepmendagri-300.2.2-2138-2025+2430-2025, berlaku 2025-06-23.
Ini adalah proyek independen yang menyediakan data siap-mesin yang diturunkan dari dokumen regulasi pemerintah Indonesia yang tersedia untuk publik. Ini bukan API resmi pemerintah, dan Kementerian Dalam Negeri (Kemendagri) tidak mendukungnya. Untuk keperluan hukum, gunakan dokumen resminya.
Apa itu “kodifikasi wilayah”
Kode dan data wilayah administrasi pemerintahan adalah penomoran nasional wilayah administrasi pemerintahan yang dikelola Kementerian Dalam Negeri. Setiap provinsi, kabupaten, kota, kecamatan, kelurahan, dan desa memiliki kode angka yang dipakai di berbagai sistem pemerintahan (kependudukan, pemilu, statistik, anggaran). Aturan pemberian kode ditetapkan dalam Permendagri 58/2021. Tabel kode lengkapnya diterbitkan, dan diperbarui secara berkala, dalam bentuk Keputusan Menteri Dalam Negeri. Yang berlaku saat ini adalah Kepmendagri 300.2.2-2138/2025.
Tingkat wilayah
| Tingkat (API) | Bahasa Indonesia | Kode | Jumlah | Keterangan |
|---|---|---|---|---|
province | Provinsi | 31 | 38 | Termasuk daerah khusus/istimewa (Aceh, DKI Jakarta, DI Yogyakarta, provinsi-provinsi di Papua). |
regency, type kabupaten | Kabupaten | 32.04 | 416 | Kode 01–69. |
regency, type kota | Kota | 32.73 | 98 | Kode 71–99. Kota bukan kabupaten: “Kabupaten Bandung” (32.04) dan “Kota Bandung” (32.73) adalah dua wilayah berbeda. |
district | Kecamatan (distrik di Papua) | 32.73.01 | 7.285 | |
village, type kelurahan | Kelurahan | 32.73.01.1001 | 8.496 | Wilayah kerja lurah sebagai perangkat kecamatan. Kode diawali angka 1. |
village, type desa | Desa (gampong, nagari, kampung, …) | 11.01.01.2001 | 75.252 | Kesatuan masyarakat hukum yang mengatur urusannya sendiri. Kode diawali angka 2. |
village, type desa_adat | Desa adat | 91.03.01.3007 | 14 | Kode diawali angka 3. Rekapitulasi resmi menghitungnya sebagai desa (total 75.266). |
Hierarkinya ketat: setiap kabupaten/kota berada di satu provinsi, setiap kecamatan di satu kabupaten/kota, dan setiap kelurahan/desa di satu kecamatan.
Provinsi 31 Daerah Khusus Ibukota Jakarta
└── Kabupaten/Kota 31.71 Kota Administrasi Jakarta Pusat
└── Kecamatan 31.71.01 Gambir
└── Kelurahan 31.71.01.1001 Gambir
Format kode
Berdasarkan Permendagri 58/2021, Pasal 4–6:
- Provinsi, 2 digit. Digit pertama menunjukkan kelompok pulau dari barat ke timur (1–2 Sumatera, 3–4 Jawa, 5 Bali dan Nusa Tenggara, 6 Kalimantan, 7 Sulawesi, 8 Maluku, 9 Papua). Digit kedua menunjukkan urutan pembentukan.
- Kabupaten/kota, kode provinsi + 2 digit.
01–69untuk kabupaten dan71–99untuk kota. - Kecamatan, kode kabupaten/kota + 2 digit.
- Kelurahan/desa, kode kecamatan + 4 digit. Digit pertama dari 4 digit itu adalah
1untuk kelurahan,2untuk desa, dan3untuk desa adat. - Jika sebuah wilayah dimekarkan, wilayah induk tetap memakai kodenya dan wilayah baru mendapat kode berikutnya. Wilayah yang berganti nama tetap memakai kode yang sama.
Kode adalah string. Simpan sebagai teks, jangan sebagai angka. Angka nol di depan itu penting ("11.01"), dan titik adalah bagian dari kode yang diterbitkan. Untuk mendapatkan bentuk 10 digit yang dipakai sebagian sistem, hapus titiknya (3171011001).
Endpoint
| Endpoint | Isi |
|---|---|
| /api/v1/meta.json | Versi dataset, tanggal berlaku, sumber, jumlah data, catatan temuan, daftar endpoint. |
| /api/v1/provinces.json | Array semua provinsi. |
| /api/v1/regencies.json | Array semua kabupaten dan kota. |
| /api/v1/districts.json | Array semua kecamatan (≈750 KB). |
| /api/v1/villages.json | Usang (tetap tersedia tanpa perubahan di v1): semua kelurahan/desa dalam satu file (≈24 MB, ≈3,1 MB terkompresi), mendekati batas 25 MiB per file di hosting. Pakai file per provinsi atau per kecamatan. |
| /api/v1/provinces/{province}.json | Satu provinsi, beserta jumlah anak dan sumbernya. |
| /api/v1/provinces/{province}/regencies.json | Kabupaten/kota dalam satu provinsi. |
| /api/v1/provinces/{province}/villages.json | Semua kelurahan/desa dalam satu provinsi (data yang sama dengan villages.json; paling besar ≈2,5 MB, ≈0,3 MB terkompresi). |
| /api/v1/regencies/{regency}/villages.json | Semua kelurahan/desa dalam satu kabupaten/kota (paling besar ≈240 KB). |
| /api/v1/regencies/{regency}.json | Satu kabupaten/kota, beserta provinsinya, jumlah anak, dan sumbernya. |
| /api/v1/regencies/{regency}/districts.json | Kecamatan dalam satu kabupaten/kota. |
| /api/v1/districts/{district}.json | Satu kecamatan, beserta kabupaten/kota, provinsi, jumlah anak, dan sumbernya. |
| /api/v1/districts/{district}/villages.json | Kelurahan/desa dalam satu kecamatan. Ini juga cara mencari satu kelurahan/desa: ambil 8 karakter pertama kodenya sebagai kode kecamatan. |
| /api/v1/changes.json | Indeks daftar perubahan antar-dokumen sumber. |
| /api/v1/export/indonesia-regions.{csv|json|xml|sql|xlsx|pdf} | Seluruh dataset sebagai satu file unduhan per format. |
| /api/v1/postal-codes/{3 digit pertama}.json | Pencarian kode pos: semua kelurahan/desa dengan kode pos tertentu (lihat Kode pos). |
| /api/v1/csv/{provinces|regencies|districts|villages}.csv | Data yang sama dalam format CSV, untuk spreadsheet dan impor massal. |
Kode yang tidak dikenal menghasilkan HTTP 404. Tidak ada file per kelurahan/desa, karena 83.762 file tambahan akan melampaui batas jumlah file Cloudflare.
Nama field dan path API sengaja memakai bahasa Inggris (province, regency, district, village) agar konsisten di semua bahasa pemrograman; isinya tetap nama resmi dalam bahasa Indonesia.
GET /api/v1/provinces.json
[
{"code":"11","name":"Aceh","source_page":31,"latitude":4.2…,"longitude":96.9…,"spatial_status":"available","bbox":[95.0…,2.0…,98.3…,6.1…]},
{"code":"12","name":"Sumatera Utara","source_page":320,"latitude":…,"longitude":…,"spatial_status":"available","bbox":[…]},
...
]
GET /api/v1/provinces/31/regencies.json
[
{"code":"31.01","name":"Kabupaten Administrasi Kepulauan Seribu","type":"kabupaten","province_code":"31","source_page":1334},
{"code":"31.71","name":"Kota Administrasi Jakarta Pusat","type":"kota","province_code":"31","source_page":1335},
...
]
GET /api/v1/districts/31.71.01.json
{
"code": "31.71.01",
"name": "Gambir",
"level": "district",
"regency": { "code": "31.71", "name": "Kota Administrasi Jakarta Pusat", "type": "kota" },
"province": { "code": "31", "name": "Daerah Khusus Ibukota Jakarta" },
"counts": { "villages": 6, "kelurahan": 6, "desa": 0, "desa_adat": 0 },
"source": { "document": "KEPMENDAGRI-300-2-2-2138-2025.pdf", "page": 1335 },
"latitude": -6.17…,
"longitude": 106.82…,
"spatial_status": "available",
"bbox": [106.80…, -6.19…, 106.84…, -6.16…],
"links": {
"self": "/api/v1/districts/31.71.01.json",
"villages": "/api/v1/districts/31.71.01/villages.json",
"regency": "/api/v1/regencies/31.71.json",
"province": "/api/v1/provinces/31.json",
"boundary": "/api/v1/boundaries/regencies/31.71/districts.geojson"
},
"geometry": {"type":"Polygon","coordinates":[[[106.81…,-6.16…], …]]}
}
GET /api/v1/districts/31.71.01/villages.json
[
{"code":"31.71.01.1001","name":"Gambir","type":"kelurahan","district_code":"31.71.01","regency_code":"31.71","province_code":"31","source_page":1335},
...
]
Field data
Endpoint daftar mengembalikan array berisi data datar. Bentuk data selalu sama, baik dari daftar lengkap maupun dari daftar hierarki.
| Field | Tingkat | Keterangan |
|---|---|---|
code | semua | Kode resmi, string, bertitik. |
name | semua | Nama persis seperti tercetak di dokumen sumber (lihat normalisasi). Nama kabupaten/kota menyertakan jenisnya: “Kabupaten …” atau “Kota …”. |
type | kabupaten/kota, kelurahan/desa | kabupaten atau kota; kelurahan, desa, atau desa_adat. Diturunkan dari kode dan dicocokkan dengan kolom tabel tempat nama itu tercetak. |
province_code | kabupaten/kota, kecamatan, kelurahan/desa | Provinsi induk. |
regency_code | kecamatan, kelurahan/desa | Kabupaten/kota induk. |
district_code | kelurahan/desa | Kecamatan induk. |
source_page | semua | Halaman PDF sumber (meta.json → source.base_document.file), dihitung dari 1, tempat data itu tercantum di tabel rincian. Ini adalah urutan halaman PDF, bukan nomor yang tercetak di halaman. |
latitude, longitude | semua | Titik representatif poligon batas wilayah BIG, dalam derajat desimal: titik yang dijamin berada di dalam poligon (lihat Batas wilayah administrasi). null jika BIG tidak memiliki poligon untuk kode tersebut. |
spatial_status | semua | available (poligon BIG tergabung lewat kode) atau not_available. |
postal_code | kelurahan/desa | Kode pos Pos Indonesia, string 5 digit, atau null jika tidak ada kecocokan persis (lihat Kode pos). |
bbox | semua | Kotak batas poligon, [min_longitude, min_latitude, max_longitude, max_latitude], atau null. Berguna untuk menyesuaikan tampilan peta. |
Endpoint detail (/provinces/{code}.json, /regencies/{code}.json, /districts/{code}.json) menambahkan level, objek induk, counts (jumlah anak), source (document dan page), serta links ke endpoint terkait. Endpoint detail juga memuat poligon wilayah: geometry (GeoJSON Polygon/MultiPolygon, atau null) dan links.boundary (berkas batas wilayah asalnya). Kelurahan/desa tidak memiliki endpoint detail; poligonnya ada di /api/v1/boundaries/regencies/{regency}/villages.geojson dan unduhan GeoJSON. Endpoint detail juga memuat postal_codes: daftar kode pos kelurahan/desa di wilayah itu, terurut.
Pulau dan koordinat
Tabel pulau di keputusan (Lampiran D.c) memuat 17.374 pulau bernama. Setiap pulau memiliki kode (NN.NN.4NNNN), nama, koordinat titik, luas (jika tercantum), dan status berpenduduk (BP) atau tidak berpenduduk (TBP). Total rekapitulasi 17.380 juga menghitung 6 pulau besar (Sumatera, Jawa, Kalimantan, Sulawesi, Timor, Papua) yang tidak memiliki baris. Pulau yang melintasi beberapa kabupaten/kota (misalnya Pulau Nias) memakai kode tingkat provinsi NN.00.4NNNN dan regency_code: null.
Titik pulau ini adalah satu-satunya koordinat di dokumen sumber. Keputusan tersebut tidak memuat batas maupun titik pusat provinsi, kabupaten/kota, kecamatan, atau kelurahan/desa. Keduanya berasal dari BIG, sebagai dataset terpisah dengan atribusinya sendiri (lihat Batas wilayah administrasi).
| Endpoint | Isi |
|---|---|
| /api/v1/islands.json | Semua pulau (≈5,7 MB). |
| /api/v1/islands.geojson | Pulau yang sama dalam bentuk GeoJSON FeatureCollection berupa titik, untuk peta dan aplikasi GIS (≈0,4 MB terkompresi). |
| /api/v1/provinces/{province}/islands.json | Pulau dalam satu provinsi, termasuk pulau tingkat provinsi. |
| /api/v1/regencies/{regency}/islands.json | Pulau dalam satu kabupaten/kota (array kosong jika tidak ada). |
Tidak ada daftar pulau per kecamatan: keputusan menetapkan pulau ke kabupaten/kota (atau, untuk pulau yang melintasi beberapa kabupaten/kota, ke provinsi), tidak pernah ke kecamatan. Menurunkannya dari batas wilayah BIG juga tidak memadai, karena hanya sekitar sepertiga titik pulau yang jatuh di dalam batas kecamatan; sebagian besar adalah pulau kecil yang titiknya berada di perairan atau di daratan yang terlalu kecil untuk poligon yang disederhanakan.
{"code":"11.10.40082","name":"Pulau Mangkir Gadang","regency_code":"11.10","province_code":"11",
"latitude":2.146942,"longitude":98.124719,"latitude_dms":"02°08'48.99\" U","longitude_dms":"098°07'28.99\" T",
"area_km2":0.0748,"inhabited":false,"remark":"Berita Acara Kesepakatan Bersama ...",
"source_document":"KEPMENDAGRI-300-2-2-2430-2025.pdf","source_page":14}
latitude/longitudeadalah derajat desimal hasil konversi dari derajat-menit-detik yang tercetak (U/S= utara/selatan,T/B= timur/barat), dibulatkan 6 desimal. Nilai tercetaknya disimpan dilatitude_dms/longitude_dms. Keputusan tersebut tidak menyebutkan datum.inhabitedbernilaitrue(BP),false(TBP), ataunulljika statusnya tidak tercantum (2.793 pulau).area_km2bernilainulljika luasnya tidak tercantum.- Setiap pulau mencantumkan
source_document-nya sendiri. Kepmendagri 300.2.2-2430/2025 memindahkan Pulau Lipan, Mangkir Gadang, Mangkir Ketek, dan Panjang dari Kabupaten Tapanuli Tengah (12.01) ke Kabupaten Aceh Singkil (11.10, kode baru 11.10.40081–40084), sehingga keempatnya merujuk ke perubahan tersebut.
Peta pulau menampilkan seluruh pulau di atas peta dasar OpenFreeMap, dengan filter provinsi, kabupaten/kota, dan status.
Batas wilayah administrasi
Poligon batas provinsi, kabupaten/kota, kecamatan, dan kelurahan/desa berasal dari Badan Informasi Geospasial (BIG). Poligon tersebut digabungkan dengan data Kemendagri di API ini berdasarkan kode yang persis sama (field KDPPUM, KDPKAB, KDCPUM, dan KDEPUM milik BIG). Nama tidak pernah dicocokkan, dan nama, kode, serta hierarki selalu berasal dari API ini. Setiap data tetap ada di file batas. Data tanpa poligon BIG memiliki "geometry": null dan "spatial_status": "not_available", sedangkan fitur BIG yang kodenya tidak ada di dataset terkini tidak disertakan dan dicatat di laporan.
| Tingkat | Dengan batas / jumlah data | Layer sumber BIG |
|---|---|---|
| Provinsi | — / — | gis/rest/services/STIG/Batas_Provinsi/MapServer/0 |
| Kabupaten/Kota | — / — | gis/rest/services/DISIGT/BatasWilayah/FeatureServer/0 |
| Kecamatan | — / — | rbi/rest/services/BATASWILAYAH/BATAS_KECAMATAN_AR/MapServer/0 |
| Kelurahan/Desa | — / — | rbi/rest/services/BATASWILAYAH/BATAS_DESAKEL_AR/MapServer/0 |
| Endpoint | Isi |
|---|---|
| /api/v1/boundaries/provinces.geojson | Semua provinsi (muatan awal peta, ≈0,14 MB terkompresi). |
| /api/v1/boundaries/provinces/{province}/regencies.geojson | Kabupaten/kota dalam satu provinsi. |
| /api/v1/boundaries/regencies/{regency}/districts.geojson | Kecamatan dalam satu kabupaten/kota. |
| /api/v1/boundaries/regencies/{regency}/villages.geojson | Kelurahan/desa dalam satu kabupaten/kota. Dikelompokkan per kabupaten/kota, bukan per kecamatan, agar jumlah file tetap di bawah batas Cloudflare. Saring dengan district_code. |
{"type":"Feature","id":"31.71.01.1001","properties":{"code":"31.71.01.1001","name":"Gambir","level":"village",
"type":"kelurahan","district_code":"31.71.01","regency_code":"31.71","province_code":"31",
"latitude":-6.17…,"longitude":106.82…,"spatial_status":"available"},"geometry":{"type":"Polygon","coordinates":[…]}}
latitude/longitudeadalah titik representatif: titik terjauh dari tepi (pole of inaccessibility) pada poligon terbesar wilayah tersebut. Titik ini dijamin berada di dalam poligon yang diterbitkan, dan hal itu diperiksa untuk setiap wilayah. Ini bukan centroid, dan bukan pusat tampilan peta. Koordinat GeoJSON berurutan[longitude, latitude].- Geometri disederhanakan untuk web dengan mapshaper (Visvalingam, menjaga topologi, sehingga wilayah yang bertetangga tetap berbagi batas yang sama). Lubang, multipolygon, dan pulau kecil tetap dipertahankan, dan perpotongan diperbaiki. Jika poligon BIG saling tumpang tindih, bagian yang tumpang tindih diberikan ke poligon yang lebih kecil, sehingga kelurahan/desa yang tergambar sebagian di dalam wilayah tetangganya tetap memiliki luasnya. Interval: provinsi 1 km, kabupaten/kota 250 m, kecamatan 60 m, kelurahan/desa 20 m. Ini geometri tampilan, bukan batas hukum hasil survei.
- BIG hanya dipakai saat build. Browser tidak pernah menghubungi BIG; file-filenya statis seperti bagian API lainnya.
- Layer kecamatan yang semula ditentukan (
BATAS_WILAYAH/MapServer/14) hanya berisi 66 kecamatan di Kota Kendari dan Kabupaten Konawe. Karena itu dipakai layer kecamatan nasionalBATAS_KECAMATAN_ARdari folder layanan BIG yang sama.
Jelajahi batas wilayah di peta, dari provinsi hingga kelurahan/desa.
Kode pos
Kode pos berasal dari Pos Indonesia (kodepos.posindonesia.co.id), diambil —. — dari — kelurahan/desa memiliki kode pos (— kode berbeda). Keputusan Mendagri tidak memuat kode pos.
| Endpoint | Isi |
|---|---|
| /api/v1/postal-codes/{3 digit pertama}.json | Semua kelurahan/desa per kode pos, dikelompokkan menurut tiga digit pertama (satu file per kode akan melebihi batas jumlah file hosting). |
GET /api/v1/postal-codes/101.json
{"10110":[{"code":"31.71.01.1001","name":"Gambir","district_code":"31.71.01","regency_code":"31.71","province_code":"31"}], …}
- Metode. Pos Indonesia tidak menyediakan unduhan massal, sehingga situsnya ditanya sekali per kode pos saat build (satu permintaan per detik; browser tidak pernah menghubunginya). Daftar kode yang ditanyakan adalah gabungan dua dataset publik: Kode Pos Desa Kelurahan di Indonesia (Satu Data Indonesia / Diskominfo Jawa Barat, 2023) dan cahyadsn/wilayah_kodepos (MIT). Penetapan kode pos dari kedua dataset itu tidak dipakai sebagai data.
- Pencocokan. Pos Indonesia menerbitkan nama, bukan kode wilayah. Setiap hasil dicocokkan berdasarkan nama yang sama persis setelah normalisasi (huruf besar/kecil, spasi, dan tanda baca;
KAB.danKOTA ADM.dijabarkan): kabupaten/kota, lalu kecamatan di dalamnya, lalu kelurahan/desa di kecamatan itu. Tidak ada pencocokan kira-kira. Dua kelurahan/desa bernama sama dalam satu kecamatan, atau satu kelurahan/desa dengan dua kode berbeda, diberinull. - Mengapa bukan kedua dataset itu. Dari semua kelurahan/desa yang cocok dengan Pos Indonesia, dataset pemerintah memberi kode pos yang sama untuk 77% kelurahan/desa yang dicakupnya dan cahyadsn untuk 61%; keduanya hanya sama satu sama lain pada 70% kelurahan/desa.
Contoh klien
curl
curl -s https://indonesia-region.caturseptian.site/api/v1/regencies/32.73/districts.json
JavaScript / TypeScript
type Village = {
code: string; name: string; type: "kelurahan" | "desa" | "desa_adat";
district_code: string; regency_code: string; province_code: string; source_page: number;
};
const BASE = "https://indonesia-region.caturseptian.site/api/v1";
export async function villagesOf(districtCode: string): Promise<Village[]> {
const res = await fetch(`${BASE}/districts/${districtCode}/villages.json`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// Cari satu kelurahan/desa berdasarkan kode: datanya dikelompokkan per kecamatan.
export async function village(code: string) {
return (await villagesOf(code.slice(0, 8))).find((v) => v.code === code) ?? null;
}
Python
import requests
BASE = "https://indonesia-region.caturseptian.site/api/v1"
meta = requests.get(f"{BASE}/meta.json", timeout=30).json()
print(meta["dataset_version"], meta["counts"]["villages"])
regencies = requests.get(f"{BASE}/provinces/34/regencies.json", timeout=30).json()
print([r["name"] for r in regencies])
Go
type Regency struct {
Code string `json:"code"`
Name string `json:"name"`
Type string `json:"type"`
ProvinceCode string `json:"province_code"`
SourcePage int `json:"source_page"`
}
resp, err := http.Get("https://indonesia-region.caturseptian.site/api/v1/provinces/32/regencies.json")
if err != nil { log.Fatal(err) }
defer resp.Body.Close()
var regencies []Regency
if err := json.NewDecoder(resp.Body).Decode(®encies); err != nil { log.Fatal(err) }
PHP
$json = file_get_contents('https://indonesia-region.caturseptian.site/api/v1/regencies/35.78/districts.json');
$districts = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
foreach ($districts as $d) {
echo $d['code'], ' ', $d['name'], PHP_EOL;
}
Java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(
URI.create("https://indonesia-region.caturseptian.site/api/v1/provinces.json")).build();
String body = client.send(request, HttpResponse.BodyHandlers.ofString()).body();
// parse dengan Jackson, Gson, ... ; simpan "code" sebagai String
Contoh-contoh ini memakai deployment resmi, https://indonesia-region.caturseptian.site. Jika halaman ini disajikan dari preview, alamat itulah yang ditampilkan.
Ukuran dan performa
Telusuri hierarkinya alih-alih mengunduh daftar lengkap. Pemilih berjenjang provinsi → kabupaten/kota → kecamatan → kelurahan/desa cukup memakai paling banyak empat request kecil:
| File | Tanpa kompresi | gzip |
|---|---|---|
provinces.json | 2 KB | 0,6 KB |
regencies.json | 54 KB | 7 KB |
districts.json | 753 KB | 73 KB |
villages.json (usang) | 24 MB | 3,1 MB |
satu provinces/{code}/villages.json | ≤ 2,5 MB | ≤ 0,3 MB |
search/villages.json (kode, nama, jenis semua kelurahan/desa) | 3,3 MB | 0,6 MB |
satu districts/{code}/villages.json | ≤ 16 KB | ≤ 2 KB |
Cloudflare mengompresi respons dan menyajikannya dari cache edge.
Unduhan
Seluruh dataset dalam satu file, dibuat dari data tervalidasi yang sama di setiap deploy. Ukuran dan checksum SHA-256 tercantum di meta.json → downloads.
| Format | File | Ukuran | Isi |
|---|---|---|---|
| CSV | indonesia-regions.csv | — | Semua tingkat dalam satu tabel (satu baris per wilayah: level, kode, nama, jenis, kode induk, halaman sumber, latitude, longitude, status spasial). |
| JSON | indonesia-regions.json | — | Satu objek berisi array provinces, regencies, districts, villages beserta metadata dataset. |
| XML | indonesia-regions.xml | — | <indonesia-regions> dengan satu elemen per wilayah; field disimpan sebagai atribut. |
| SQL | indonesia-regions.sql | — | CREATE TABLE + INSERT untuk empat tabel dengan primary key dan foreign key. Portabel: SQLite, PostgreSQL, MySQL/MariaDB. |
| Excel (XLSX) | indonesia-regions.xlsx | — | Workbook berisi sheet About dan satu sheet per tingkat; kode disimpan sebagai teks, baris judul dibekukan dengan filter. |
| indonesia-regions.pdf | — | Daftar seluruh wilayah siap cetak ukuran A4 (sekitar 1.270 halaman). |
JSON dan XML hanya memuat tingkat wilayah; data pulau ada di indonesia-islands.json dan indonesia-islands.xml, karena satu file akan melebihi batas 25 MiB per file di hosting. CSV hanya memuat wilayah; SQL, XLSX, dan PDF memuat keduanya. Kelurahan/desa memuat postal_code di semua format.
Setiap format tabel memuat titik representatif dan status setiap wilayah (latitude, longitude, spatial_status; kosong jika BIG tidak memiliki poligon). Poligon tidak muat di sel tabel, sehingga tersedia sebagai GeoJSON:
| Tingkat | File | Isi |
|---|---|---|
| Provinsi | export/boundaries/provinces.geojson | Seluruh 38 provinsi. |
| Kabupaten/Kota | export/boundaries/regencies.geojson | Seluruh 514 kabupaten/kota. |
| Kecamatan | export/boundaries/districts-{province}.geojson | Kecamatan, satu file per provinsi (mis. districts-31.geojson). |
| Kelurahan/Desa | export/boundaries/villages-{province}.geojson | Kelurahan/desa, satu file per provinsi (mis. villages-31.geojson). |
Kecamatan dan kelurahan/desa dipecah per provinsi karena satu file nasional akan melebihi batas 25 MiB per file di hosting. Jumlah fitur, ukuran, dan checksum SHA-256 ada di meta.json → boundaries.downloads. Fiturnya sama dengan yang ada di /api/v1/boundaries/.
Untuk mengekspor sebagian data saja (satu provinsi, satu kecamatan, …), buka penjelajah API, pilih wilayah, lalu gunakan Unduh respons ini. Keenam format yang sama dibuat langsung di browser dari respons yang sedang ditampilkan, ditambah GeoJSON berisi poligon wilayah yang ditampilkan. Kode tetap berupa teks di semua format.
Pencarian
Tidak ada endpoint pencarian di sisi server, karena situs statis tidak bisa menjalankan query. Untuk pencarian, unduh daftar yang dibutuhkan lalu saring di sisi klien. regencies.json dan districts.json cukup kecil untuk fitur ketik-langsung-cari (seperti di penjelajah API). Untuk kelurahan/desa, persempit dulu ke satu kecamatan, atau muat search/villages.json sekali ({"fields":["code","name","type"],"rows":[…]}, 0,6 MB terkompresi; peta melakukannya) lalu indeks secara lokal.
Versi
- Versi API (
/api/v1/): struktur URL dan bentuk data. Dalam v1, field bisa bertambah tetapi tidak pernah dihapus atau diganti namanya. Perubahan yang tidak kompatibel akan diterbitkan di/api/v2/, sementara v1 tetap tersedia. - Versi dataset (
meta.json → dataset_version): dinamai sesuai dokumen pemerintah yang menjadi sumbernya, misalnyakepmendagri-300.2.2-2138-2025+2430-2025(keputusan dasar + perubahannya). Versi ini hanya berubah jika ada dokumen resmi baru yang dimasukkan. Tidak ada nomor versi semantik karangan untuk data pemerintah. effective_datedanlast_updatedberasal dari dokumen (tanggal penetapan perubahan terakhir), bukan dari waktu build. Build ulang menghasilkan file yang identik byte demi byte.
Jika aplikasi Anda perlu mengunci dataset tertentu, periksa dataset_version di meta.json.
Data historis
Dua tabel kode sebelumnya diekstrak dengan pipeline yang sama dan disimpan sebagai snapshot internal:
- Permendagri 137/2017 (34 provinsi, 83.437 kelurahan/desa)
- Kepmendagri 100.1.1-6117/2022 (37 provinsi, 83.763 kelurahan/desa), dicabut oleh 300.2.2-2138/2025
/api/v1/changes.json berisi perbedaan antar-dokumen yang berurutan. Kode yang ada di kedua dokumen tetapi namanya berbeda dicatat sebagai renamed (ganti nama); kode yang hanya ada di salah satunya dicatat sebagai added (ditambahkan) atau removed (dihapus). Perbedaan huruf besar/kecil, spasi, atau singkatan “KAB.” diabaikan. Jika sebuah wilayah pindah induk, kodenya ikut berubah (misalnya kabupaten yang pindah ke Papua Barat Daya, 92.xx → 96.xx pada 2022–2025). Perpindahan seperti ini tampil sebagai removed + added dan tidak pernah ditebak. API saat ini hanya menyajikan dataset terkini; snapshot historis adalah file data dan tidak mengubah endpoint /api/v1.
Asal-usul data
Setiap nilai bisa ditelusuri ke satu halaman dokumen resmi.
PDF resmi (sources/pdf, tidak di-deploy)
→ extract koordinat kata via poppler pdftotext -bbox, baris tabel per halaman
→ normalize hierarki, jenis, pencocokan silang, rekonsiliasi dengan angka tercetak
→ validate format, keunikan, induk, jumlah, file hasil generate
→ build JSON statis di public/api/v1 → Cloudflare
Dokumen sumber
| Dokumen | Ditetapkan | Peran |
|---|---|---|
| Kepmendagri 300.2.2-2138 Tahun 2025 | 2025-04-25 | Tabel kode yang berlaku. Sumber semua data. |
| Kepmendagri 300.2.2-2430 Tahun 2025 | 2025-06-23 | Mengubah 2138/2025 khusus data pulau: 4 pulau berpindah dari Sumatera Utara ke Kabupaten Aceh Singkil. Tidak ada perubahan kode maupun nama wilayah. PDF berupa gambar, diperiksa secara visual. |
| Permendagri 58 Tahun 2021 | 2021-12-13 | Aturan format dan pemberian kode. Tanpa tabel kode. |
| Kepmendagri 100.1.1-6117 Tahun 2022 | 2022-11-09 | Tabel kode sebelumnya (dicabut). Snapshot historis. |
| Permendagri 137 Tahun 2017 | 2017-12-27 | Tabel kode lama (diganti). Snapshot historis. |
| PP 72 Tahun 2019 | 2019-10-14 | Perubahan PP 18/2016 tentang Perangkat Daerah. Hanya konteks hukum; tidak memuat kode. |
Cara data saat ini diperiksa
- Data dibaca dari tabel rincian per kabupaten/kota di lampiran (Lampiran C), yang memuat hierarki lengkap beserta nomor halamannya.
- Total sama dengan rekapitulasi resmi (Lampiran A, dipastikan tidak berubah oleh perubahan 2430/2025): 38 provinsi, 416 kabupaten, 98 kota, 7.285 kecamatan, 8.496 kelurahan, dan 75.266 desa (termasuk 14 desa adat).
- Untuk seluruh 514 kabupaten/kota, jumlah kecamatan/kelurahan/desa yang tercetak di baris kabupaten/kota sama dengan jumlah baris yang tercantum di bawahnya. Hal yang sama berlaku untuk setiap kecamatan yang barisnya mencetak jumlah (6.688 dari 7.285; tabel Papua Selatan/Tengah/Pegunungan/Barat Daya tidak mencetaknya).
- Jenis setiap kelurahan/desa menurut kodenya (1/2/3) cocok dengan kolom (kelurahan atau desa) tempat namanya tercetak.
- Nama dicocokkan silang dengan tabel rekapitulasi. Satu-satunya perbedaan adalah sel rekap yang memotong nama panjang.
Normalisasi
Nama disimpan persis seperti tercetak, termasuk penggunaan " sebagai tanda apostrof di dokumen (misalnya Ra"as). Satu-satunya pengecualian adalah nama kabupaten yang dicetak dengan singkatan “Kab” (53.02 Timor Tengah Selatan dan 95.02 Pegunungan Bintang), yang ditulis lengkap menjadi “Kabupaten” seperti 414 kabupaten lainnya. Keduanya dicatat di meta.json → provenance.normalizations.
Proses pembaruan
- Saat keputusan atau perubahan baru terbit, dokumen itu dicatat beserta tanggal penetapan dan checksum-nya. Jika dokumen itu menggantikan tabel kode, dokumen tersebut menjadi dokumen dasar, dan total yang diharapkan diambil dari rekapitulasinya.
- Tabel diekstrak ulang dari PDF, lalu dinormalisasi dan divalidasi. Pembaruan ditolak jika total, induk, jenis, atau jumlah tercetak tidak cocok.
- Temuan yang memerlukan keputusan manusia diperiksa terhadap halaman PDF dan dipublikasikan di
meta.json → known_issues. Tidak ada koreksi diam-diam. - Daftar perubahan terhadap dokumen sebelumnya dibuat otomatis (
/api/v1/changes.json), dan setiap pembaruan ditinjau sebagai diff lengkap data.
Batasan dan temuan
- Luas wilayah, jumlah penduduk, dan ibu kota di keputusan tersebut belum diekstrak; data pulau sudah (lihat di atas).
- Tidak ada endpoint per kelurahan/desa (batas jumlah file). Cari kelurahan/desa melalui file kecamatannya.
- Dua pasang desa dalam keputusan yang berlaku memiliki nama sama di satu kecamatan, sesuai yang tercetak: “Tounelet Satu” (71.02.11.2003 dan 71.02.11.2018) dan “Kogekotu” (94.03.01.2011 dan 94.03.01.2018). Keduanya disimpan sesuai cetakan dan ditandai untuk ditinjau di
meta.json → known_issues. - Satu desa tercetak sebagai “Teuw*” (91.20.07.2005) tanpa catatan kaki. Disimpan sesuai cetakan.
- Tabel historis 2017 memiliki ketidaksesuaian internal (Kota Sorong 92.71 mencetak 52 kelurahan tetapi mencantumkan 41). Temuan ini dicatat secara internal dan tidak memengaruhi data terkini.
- Kumpulan sumber memuat PP 72/2019 (Perangkat Daerah), bukan Permendagri 72/2019 (yang mengubah Permendagri 137/2017). Yang terakhir tidak digunakan.
- Koordinat pulau adalah nilai sesuai cetakan. Tiga pulau di Kab. Halmahera Selatan (82.04.40451, 82.04.40458, 82.04.40463) tercetak dengan bujur Kalimantan Barat, kemungkinan besar salah ketik di sumber. Ketiganya disimpan sesuai cetakan dan ditandai di peta serta di
meta.json → known_issues. Halaman pengganti tabel pulau di 2430/2025 berupa gambar: baris yang berubah diperiksa terhadap gambar halaman, dan baris yang tidak berubah diambil dari tabel digital 2138. - Poligon batas berasal dari BIG, bukan dari keputusan. Data BIG bisa lebih lama daripada keputusan 2025, sehingga wilayah yang dibentuk atau berganti kode sejak itu bisa tidak memiliki batas (lihat jumlah di atas dan
meta.json → boundaries.levels). - Kode pos dicocokkan berdasarkan nama karena Pos Indonesia tidak menerbitkan kode wilayah. Kelurahan/desa yang berganti nama atau pindah kecamatan sejak data Pos Indonesia, serta kode pos yang tidak ada di kedua dataset kandidat, tidak memiliki kode pos. Pos Indonesia mengembalikan paling banyak 50 baris per pencarian; kode yang terpotong dilengkapi dengan pencarian per kecamatan dan per nama kelurahan/desa, dan — kode belum dapat dipastikan lengkap. Nama dibandingkan persis, sehingga kelurahan/desa yang namanya hanya berbeda ejaan tidak tercocokkan. Situs Pos Indonesia tidak mencantumkan ketentuan penggunaan; situs itu hanya ditanya secara santun saat build.
- Regulasi yang ditetapkan setelah 23 Juni 2025 belum dimasukkan sampai ditambahkan ke kumpulan sumber.
CORS dan cache
API mengirim Access-Control-Allow-Origin: *, sehingga aplikasi browser di domain mana pun bisa memanggilnya. Request berupa GET sederhana dan tidak memerlukan preflight; jangan menambahkan header request khusus. Pengaturannya ada di public/_headers:
/api/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Max-Age: 86400
Cache-Control: public, max-age=3600, stale-while-revalidate=86400
Browser boleh menyimpan respons di cache selama satu jam, dan Cloudflare memvalidasinya ulang dengan ETag. JSON disajikan sebagai application/json. Halaman HTML mendapat header keamanan (CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy).
Laporkan koreksi
Koreksi harus didukung dokumen resmi. Jika Anda menemukan nama atau kode yang berbeda dari keputusan, kirim email ke hello@caturseptian.site dengan menyertakan kode, dokumen, dan halaman PDF-nya.
Atribusi data
- Dokumen sumber dan data. Kode dan nama wilayah diambil dari dokumen regulasi pemerintah Indonesia (Kementerian Dalam Negeri). Proyek ini tidak membuat klaim apa pun mengenai status hak cipta dokumen tersebut, tidak melisensikannya ulang, dan tidak mengklaim kepemilikan atas datanya. Pengguna bertanggung jawab mematuhi ketentuan yang berlaku atas materi sumber.
- Mohon cantumkan sumbernya saat memakai data ini, misalnya “Data: Kepmendagri 300.2.2-2138/2025 (sebagaimana diubah dengan 300.2.2-2430/2025), melalui Indonesia Region API”.