BYTETOOLS

API Wilayah Indonesia

Free Indonesian administrative regions API with no key: all 34 provinces, regencies, districts and 80,000+ villages with official codes. Tested example and live response.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-21

What is the API Wilayah Indonesia?

API Wilayah Indonesia is a free, key-free API serving Indonesia's four-level administrative hierarchy: provinces, regencies and cities, districts (kecamatan) and villages (kelurahan and desa), each with the official Kemendagri code.

Indonesian address forms need four cascading dropdowns, and building them without a reference dataset is impractical — there are more than 80,000 villages. This project publishes the Ministry of Home Affairs region list as static JSON, one file per level and per parent, which makes each request tiny and infinitely cacheable.

The id encodes the hierarchy rather than being arbitrary, and that is the detail that makes the API pleasant to work with. A province is two digits, a regency is `11.01`, a district `11.01.01` and a village `11.01.01.2001`, so the parent of any unit is its own id with the last segment removed. Names come back in upper case throughout, matching the government source, so title-case them before display unless you want your form shouting.

Quick facts

Base URL
https://www.emsifa.com/api-wilayah-indonesia/api
Authentication
No key or account. Static JSON generated from Kemendagri published data; free for any use.
Rate limit
No limit. Every endpoint is a static file, so it costs the host nothing to serve.
Pricing
Free and open source.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the API Wilayah Indonesia

Every request below was executed against the live API on 2026-08-21, and the response shown is the real body it returned — not an illustration.

1. List every Indonesian province

GET https://www.emsifa.com/api-wilayah-indonesia/api/provinces.json

curl
curl 'https://www.emsifa.com/api-wilayah-indonesia/api/provinces.json'
JavaScript (fetch)
const res = await fetch("https://www.emsifa.com/api-wilayah-indonesia/api/provinces.json");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://www.emsifa.com/api-wilayah-indonesia/api/provinces.json", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
[
  {
    "id": "11",
    "name": "ACEH"
  },
  {
    "id": "12",
    "name": "SUMATERA UTARA"
  },
  {
    "id": "13",
    "name": "SUMATERA BARAT"
  },
  {
    "id": "14",
    "name": "RIAU"
  },
  {
    "id": "15",
    "name": "JAMBI"
  },
  {
    "id": "16",
    "name": "SUMATERA SELATAN"
  },
  {
    "id": "17",
    "name": "BENGKULU"
  },
  {
    "id": "18",
    "name": "LAMPUNG"
  },
  {
    "id": "19",
    "name": "KEPULAUAN BANGKA BELITUNG"
  },
  {
    "id": "21",
    "name": "KEPULAUAN RIAU"
  },
  {
    "id": "31",
    "name": "DKI JAKARTA"
  },
  {
    "id": "32",
    "name": "JAWA BARAT"
  },
  {
    "id": "33",
    "name": "JAWA TENGAH"
  },
  {
    "id": "34",
    "name": "DI YOGYAKARTA"
  },
  {
    "id": "35",
    "name": "JAWA TIMUR"
  },
  {
    "id": "36",
    "name": "BANTEN"
  },
  {
    "id": "51",
    "name": "BALI"
  },
  {
    "id": "52",
    "name": "NUSA TENGGARA BARAT"
  },
  {
    "id": "53",
    "name": "NUSA TENGGARA TIMUR"
  },
  {
    "id": "61",
    "name": "KALIMANTAN BARAT"
  },
  {
    "id": "62",
    "name": "KALIMANTAN TENGAH"
  },
  {
    "id": "63",
    "name": "KALIMANTAN SELATAN"
  },
  {
    "id": "64",
    "name": "KALIMANTAN TIMUR"
  },
  {
    "id": "65",
    "name": "KALIMANTAN UTARA"
  },
  {
    "id": "71",
    "name": "SULAWESI UTARA"
  },
  {
    "id": "72",
    "name": "SULAWESI TENGAH"
  },
  {
    "id": "73",
    "name": "SULAWESI SELATAN"
  },
  {
    "id": "74",
    "name": "SULAWESI TENGGARA"
  },
  {
    "id": "75",
    "name": "GORONTALO"
  },
  {
    "id": "76",
    "name": "SULAWESI BARAT"
  },
  {
    "id": "8

Parameters

ParameterTypeRequiredDescription
(provinces)pathOptional`/provinces.json` returns all provinces with their two-digit ids. provinces.json
(regencies)pathOptional`/regencies/{provinceId}.json` lists regencies and cities in a province. 11.json
(districts)pathOptional`/districts/{regencyId}.json` lists the kecamatan of a regency. 1101.json
(villages)pathOptional`/villages/{districtId}.json` lists the kelurahan and desa of a district. 110101.json
(single)pathOptional`/province/{id}.json` and its siblings return one record rather than a list. 11.json

Response fields

idstring
Official Kemendagri code. Its length tells you the level: 2 digits for a province, 4 for a regency, 6 for a district, 10 for a village.
namestring
Official name in upper case, exactly as the ministry publishes it. Convert to title case for display.
(nested paths) province_id / regency_id / district_idstring
Parent identifier on the lower-level files, which lets you rebuild the tree offline.

What you can build with the API Wilayah Indonesia

  • Build the four-level cascading address selector Indonesian forms require
  • Validate an Indonesian address against official region codes
  • Assign shipping zones by province or regency
  • Seed a local database with the full region hierarchy for offline use
  • Normalise inconsistent region spellings in an existing dataset

Common errors and how to fix them

404 on a child list

The parent id is wrong, or the file name is missing its `.json` extension.

Fix: Every path ends in `.json`, and the id must be the parent's own id with dots removed — regency 11.01 becomes `/districts/1101.json`.

Names are shouting in the UI

The source data is upper case throughout.

Fix: Title-case for display, but keep the original value if you need to match against other Indonesian government datasets.

Ids lose leading zeros

Ids are zero-padded strings that loose parsers coerce to numbers.

Fix: Keep them as strings. Province "11" is fine as a number by luck; village "1101012001" is not, and neither are the dotted forms.

A region is missing

Indonesia creates and splits regencies regularly, and the static files track a specific ministry publication.

Fix: Check the repository's last update before relying on it for a newly formed region, and file an issue upstream if it is stale.

API Wilayah Indonesia — frequently asked questions

Is the Indonesian regions API free?

Yes, free with no key, account or rate limit. It publishes Ministry of Home Affairs data as static JSON files, so there is nothing to throttle.

What are the four administrative levels?

Province (provinsi), regency or city (kabupaten/kota), district (kecamatan), and village (kelurahan for urban, desa for rural). Indonesian address forms conventionally ask for all four.

How do I find a region's parent?

Strip the last segment from its id. A village id like 1101012001 belongs to district 110101, which belongs to regency 1101, which belongs to province 11 — the hierarchy is encoded in the code itself.

Can I download the whole dataset instead of calling the API?

Yes, and for a form you probably should. The GitHub repository holds every file, so you can vendor the JSON into your project and avoid a network round trip per dropdown.

Tools that pair with this API

API Wilayah Indonesia is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-21; always check the official documentation before relying on this API in production, as terms and limits can change.