# Regions, postal codes and boundaries

> Documentation index for AI agents: [/llms.txt](https://docs.apiindonesia.id/llms.txt). Every page is also available as markdown: add `.md` to the URL.

Kemendagri administrative regions from province to village, postal codes and GeoJSON boundaries.

Administrative regions use Kemendagri codes: 38 provinces, 514 regencies/cities (kabupaten/kota), 7,285 districts (kecamatan) and 83,762 villages (desa/kelurahan).

Postal codes are keyed by the same Kemendagri codes, and region boundaries are served as GeoJSON.

All endpoints need the `x-api-key` header (see [Authentication](https://docs.apiindonesia.id/authentication.md)) and return the standard [envelope](https://docs.apiindonesia.id/errors.md). A successful request costs 2 credits.

## Endpoints on this page

- [`GET /api/v1/wilayah/provinsi`](#get-api-v1-wilayah-provinsi): List provinces
- [`GET /api/v1/wilayah/provinsi/{id}`](#get-api-v1-wilayah-provinsi-id): Retrieve a province
- [`GET /api/v1/wilayah/provinsi/{id}/kabupaten`](#get-api-v1-wilayah-provinsi-id-kabupaten): List regencies/cities in a province
- [`GET /api/v1/wilayah/kabupaten`](#get-api-v1-wilayah-kabupaten): List regencies/cities
- [`GET /api/v1/wilayah/kabupaten/{id}`](#get-api-v1-wilayah-kabupaten-id): Retrieve a regency/city
- [`GET /api/v1/wilayah/kabupaten/{id}/kecamatan`](#get-api-v1-wilayah-kabupaten-id-kecamatan): List districts in a regency/city
- [`GET /api/v1/wilayah/kecamatan`](#get-api-v1-wilayah-kecamatan): List districts
- [`GET /api/v1/wilayah/kecamatan/{id}`](#get-api-v1-wilayah-kecamatan-id): Retrieve a district
- [`GET /api/v1/wilayah/kecamatan/{id}/kelurahan`](#get-api-v1-wilayah-kecamatan-id-kelurahan): List villages in a district
- [`GET /api/v1/wilayah/kelurahan`](#get-api-v1-wilayah-kelurahan): List villages
- [`GET /api/v1/wilayah/kelurahan/{id}`](#get-api-v1-wilayah-kelurahan-id): Retrieve a village
- [`GET /api/v1/wilayah/search`](#get-api-v1-wilayah-search): Search regions
- [`GET /api/v1/kodepos`](#get-api-v1-kodepos): List postal codes
- [`GET /api/v1/kodepos/lookup`](#get-api-v1-kodepos-lookup): Cross-system code lookup
- [`GET /api/v1/kodepos/search`](#get-api-v1-kodepos-search): Search postal codes
- [`GET /api/v1/kodepos/{id}`](#get-api-v1-kodepos-id): Retrieve a postal code
- [`GET /api/v1/wilayah-boundary`](#get-api-v1-wilayah-boundary): List boundaries
- [`GET /api/v1/wilayah-boundary/{code}/metadata`](#get-api-v1-wilayah-boundary-code-metadata): Boundary metadata
- [`GET /api/v1/wilayah-boundary/{code}`](#get-api-v1-wilayah-boundary-code): Boundary GeoJSON

## Regions

Indonesian administrative region data from province down to village level, complete with region codes, postal codes, and coordinates. All list endpoints support pagination.

### GET /api/v1/wilayah/provinsi

**List provinces.** Returns a list of all provinces in Indonesia.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/provinsi" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "32",
      "code": "32",
      "name": "JAWA BARAT",
      "alt_name": "Jawa Barat",
      "lat": -6.914744,
      "lng": 107.609811,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 38,
    "page": 1,
    "per_page": 20,
    "total_pages": 2
  }
}
```

### GET /api/v1/wilayah/provinsi/{id}

**Retrieve a province.** Returns a single province by its region code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Province code, e.g. 32. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/provinsi/32" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": {
    "id": "32",
    "code": "32",
    "name": "JAWA BARAT",
    "alt_name": "Jawa Barat",
    "lat": -6.914744,
    "lng": 107.609811,
    "is_active": 1
  }
}
```

### GET /api/v1/wilayah/provinsi/{id}/kabupaten

**List regencies/cities in a province.** Nested alias for listing regencies/cities by province code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Province code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/provinsi/94/kabupaten" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "9401",
      "province_id": "94",
      "name": "Kabupaten Nabire",
      "type": "kabupaten"
    }
  ],
  "meta": {
    "total": 8,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

### GET /api/v1/wilayah/kabupaten

**List regencies/cities.** Returns a list of regencies and cities, optionally filtered by province.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `provinsi_id` | query | no | string | Filter by province code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kabupaten" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "3273",
      "province_id": "32",
      "code": "3273",
      "name": "KOTA BANDUNG",
      "alt_name": "Kota Bandung",
      "type": "kota",
      "is_city": 1,
      "lat": -6.9175,
      "lng": 107.6191,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 27,
    "page": 1,
    "per_page": 20,
    "total_pages": 2
  }
}
```

### GET /api/v1/wilayah/kabupaten/{id}

**Retrieve a regency/city.** Returns a single regency/city by its region code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Regency/city code, e.g. 3273. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kabupaten/3273" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": {
    "id": "3273",
    "province_id": "32",
    "code": "3273",
    "name": "KOTA BANDUNG",
    "alt_name": "Kota Bandung",
    "type": "kota",
    "is_city": 1,
    "lat": -6.9175,
    "lng": 107.6191,
    "is_active": 1
  }
}
```

### GET /api/v1/wilayah/kabupaten/{id}/kecamatan

**List districts in a regency/city.** Nested alias for listing districts by regency/city code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Regency/city code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kabupaten/9401/kecamatan" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "940101",
      "regency_id": "9401",
      "name": "Nabire"
    }
  ],
  "meta": {
    "total": 15,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

### GET /api/v1/wilayah/kecamatan

**List districts.** Returns a list of districts, optionally filtered by regency/city.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `kabupaten_id` | query | no | string | Filter by regency/city code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kecamatan" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "327301",
      "regency_id": "3273",
      "code": "327301",
      "name": "SUKASARI",
      "alt_name": "Sukasari",
      "lat": -6.8636,
      "lng": 107.5843,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 30,
    "page": 1,
    "per_page": 20,
    "total_pages": 2
  }
}
```

### GET /api/v1/wilayah/kecamatan/{id}

**Retrieve a district.** Returns a single district by its region code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | District code, e.g. 327301. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kecamatan/327301" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": {
    "id": "327301",
    "regency_id": "3273",
    "code": "327301",
    "name": "SUKASARI",
    "alt_name": "Sukasari",
    "lat": -6.8636,
    "lng": 107.5843,
    "is_active": 1
  }
}
```

### GET /api/v1/wilayah/kecamatan/{id}/kelurahan

**List villages in a district.** Nested alias for listing villages and customary villages by district code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | District code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kecamatan/940101/kelurahan" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "9401011001",
      "district_id": "940101",
      "name": "Wonorejo",
      "type": "kelurahan"
    }
  ],
  "meta": {
    "total": 11,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

### GET /api/v1/wilayah/kelurahan

**List villages.** Returns a list of villages complete with postal codes, optionally filtered by district.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `kecamatan_id` | query | no | string | Filter by district code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kelurahan" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "3273011001",
      "district_id": "327301",
      "code": "3273011001",
      "name": "ISOLA",
      "alt_name": "Isola",
      "type": "kelurahan",
      "postal_code": "40154",
      "is_courier_support": 1,
      "lat": -6.8593,
      "lng": 107.5921,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 4,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

### GET /api/v1/wilayah/kelurahan/{id}

**Retrieve a village.** Returns a single village by its region code.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Village code, e.g. 3273011001. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/kelurahan/3273011001" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": {
    "id": "3273011001",
    "district_id": "327301",
    "code": "3273011001",
    "name": "ISOLA",
    "alt_name": "Isola",
    "type": "kelurahan",
    "postal_code": "40154",
    "is_courier_support": 1,
    "lat": -6.8593,
    "lng": 107.5921,
    "is_active": 1
  }
}
```

### GET /api/v1/wilayah/search

**Search regions.** Searches region names across all levels at once (province, regency, district, village). The level field indicates the region level of each result.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `q` | query | yes | string | Search keyword, minimum 2 characters. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah/search?q=bandung" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "3273",
      "name": "KOTA BANDUNG",
      "alt_name": "Kota Bandung",
      "level": "kabupaten"
    },
    {
      "id": "3204",
      "name": "KABUPATEN BANDUNG",
      "alt_name": "Kabupaten Bandung",
      "level": "kabupaten"
    }
  ],
  "meta": {
    "total": 12,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

## Postal Codes

Directory of 83,000+ postal code records per village across Indonesia, with the regional hierarchy from province to village, keyed by Kemendagri region codes.

- One record per village, with its place in the hierarchy
- Official BPS region codes (SIG BPS 2025) filled for about 96% of records
- Some newer villages have no BPS counterpart yet
- Static data, sourced from the official dataset

### GET /api/v1/kodepos

**List postal codes.** Returns paginated postal codes with explicit Kemendagri administrative codes. BPS code fields and filters are available for 96% of records (official SIG BPS 2025 bridge). A small number of newer villages have no BPS counterpart yet.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `provinsi_id` | query | no | string | Filter by province code, e.g. 32. |
| `kabupaten_id` | query | no | string | Filter by regency/city code, e.g. 3273. |
| `kecamatan_id` | query | no | string | Filter by 6-digit Kemendagri district code, e.g. 327301. |
| `kode_pos` | query | no | string | Exact 5-digit postal-code filter. |
| `bps_province_code` | query | no | string | BPS province code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_regency_code` | query | no | string | BPS regency/city code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_district_code` | query | no | string | BPS district code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_village_code` | query | no | string | BPS village code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `kemendagri_province_code` | query | no | string | Kemendagri province code. |
| `kemendagri_regency_code` | query | no | string | Kemendagri regency/city code. |
| `kemendagri_district_code` | query | no | string | Kemendagri district code. |
| `kemendagri_village_code` | query | no | string | Kemendagri village code. |
| `page` | query | no | integer | Page to retrieve. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/kodepos" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "kp_3273011001",
      "village_code": "3273011001",
      "village_name": "Sukarasa",
      "district_code": "327301",
      "district_name": "Sukasari",
      "regency_code": "3273",
      "regency_name": "Kota Bandung",
      "province_code": "32",
      "province_name": "Jawa Barat",
      "postal_code": "40151",
      "kode_pos": "40151",
      "bps_village_code": null,
      "kemendagri_village_code": "3273011001",
      "source_version": "legacy-v1",
      "crosswalk_source_version": null,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 151,
    "page": 1,
    "per_page": 20,
    "total_pages": 8
  }
}
```

### GET /api/v1/kodepos/lookup

**Cross-system code lookup.** Exact lookup by postal or Kemendagri code. At least one filter is required. Lookup by BPS code also works for the roughly 96% of records that have a BPS counterpart.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `kode_pos` | query | no | string | 5-digit postal code. |
| `bps_province_code` | query | no | string | BPS province code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_regency_code` | query | no | string | BPS regency/city code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_district_code` | query | no | string | BPS district code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `bps_village_code` | query | no | string | BPS village code. Official BPS code (SIG BPS 2025); filled for about 96% of records, some newer villages have no BPS counterpart yet. |
| `kemendagri_province_code` | query | no | string | Kemendagri province code. |
| `kemendagri_regency_code` | query | no | string | Kemendagri regency/city code. |
| `kemendagri_district_code` | query | no | string | Kemendagri district code. |
| `kemendagri_village_code` | query | no | string | Kemendagri village code. |
| `page` | query | no | integer | Page. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/kodepos/lookup" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "kp_3273011001",
      "kode_pos": "40151",
      "bps_village_code": null,
      "kemendagri_village_code": "3273011001",
      "source_version": "legacy-v1",
      "crosswalk_source_version": null
    }
  ]
}
```

### GET /api/v1/kodepos/search

**Search postal codes.** Searches postal codes by village name or postal code number.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `q` | query | yes | string | Keyword, minimum 2 characters. Can be a village name or postal code. |
| `page` | query | no | integer | Page. Defaults to 1. |
| `per_page` | query | no | integer | Items per page. Defaults to 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/kodepos/search?q=40151" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": [
    {
      "id": "kp_3273011001",
      "village_code": "3273011001",
      "village_name": "Sukarasa",
      "district_code": "327301",
      "district_name": "Sukasari",
      "regency_code": "3273",
      "regency_name": "Kota Bandung",
      "province_code": "32",
      "province_name": "Jawa Barat",
      "postal_code": "40151",
      "kode_pos": "40151",
      "bps_village_code": null,
      "kemendagri_village_code": "3273011001",
      "source_version": "legacy-v1",
      "crosswalk_source_version": null,
      "is_active": 1
    }
  ],
  "meta": {
    "total": 1,
    "page": 1,
    "per_page": 20,
    "total_pages": 1
  }
}
```

### GET /api/v1/kodepos/{id}

**Retrieve a postal code.** Returns a single postal code entry by ID.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | yes | string | Postal code entry ID, e.g. kp_3273011001. |

```bash
curl "https://use.apiindonesia.id/api/v1/kodepos/kp_3273011001" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "data": {
    "id": "kp_3273011001",
    "village_code": "3273011001",
    "village_name": "Sukarasa",
    "district_code": "327301",
    "district_name": "Sukasari",
    "regency_code": "3273",
    "regency_name": "Kota Bandung",
    "province_code": "32",
    "province_name": "Jawa Barat",
    "postal_code": "40151",
    "is_active": 1
  }
}
```

## Administrative Boundaries

Province-to-village administrative GeoJSON.

### GET /api/v1/wilayah-boundary

**List boundaries.** Active boundary metadata.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `level` | query | no | string | province, regency, district, village. |
| `page` | query | no | integer | Page, default 1. |
| `per_page` | query | no | integer | Default 20, maximum 100. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah-boundary" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "success": true,
  "data": [
    {
      "code": "31",
      "name": "DKI Jakarta",
      "level": "province",
      "centroid_lat": -6.2,
      "centroid_lng": 106.8,
      "source_version": "2026.06",
      "license": "CC BY 4.0",
      "attribution": "Data boundary dari open-admin-data/indonesia-administrative-divisions oleh jakkrapongt, dilisensikan CC BY 4.0",
      "geometry_type": "MultiPolygon"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 1,
    "total_pages": 1
  }
}
```

### GET /api/v1/wilayah-boundary/{code}/metadata

**Boundary metadata.** Source, license, GeoJSON URL.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `code` | path | yes | string | Dotted code, e.g. 31. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah-boundary/31/metadata" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "success": true,
  "data": {
    "code": "31",
    "name": "DKI Jakarta",
    "level": "province",
    "source": "open-admin-data/indonesia-administrative-divisions",
    "source_version": "2026.06",
    "license": "CC BY 4.0",
    "attribution": "Data boundary dari open-admin-data/indonesia-administrative-divisions oleh jakkrapongt, dilisensikan CC BY 4.0",
    "geometry_type": "MultiPolygon",
    "status": "active",
    "url": "https://cdn.apiindonesia.id/api/v1/wilayah-boundary/31"
  }
}
```

### GET /api/v1/wilayah-boundary/{code}

**Boundary GeoJSON.** GeoJSON application/geo+json; X-Data-* headers carry source, version, license and attribution. Illustrative geometry.

| Parameter | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `code` | path | yes | string | Dotted region code. |

```bash
curl "https://use.apiindonesia.id/api/v1/wilayah-boundary/31" \
  -H "x-api-key: YOUR_API_KEY"
```

Example response (shortened):

```json
{
  "type": "FeatureCollection",
  "features": []
}
```
