Free Indonesian Administrative Regions API
Live API: https://konoland-api.vercel.app 🆓 Free to use!
Konoha Land API is a free, open-source REST API providing comprehensive data about Indonesian administrative regions (Provinces, Regencies, Districts, and Villages).
Inspired by: Wilayah Nusantara API by @theodevoid
- 🆓 100% Free - No API keys required
- 🚀 Fast & Reliable - Powered by Vercel serverless
- 📊 Latest 2025 Data - 38 provinces, 514 regencies, 7,285 districts, 83,762 villages
- 📮 Complete Postal Codes - 100% coverage for all villages
- 🔄 Backward Compatible - Drop-in replacement for legacy API
- 📦 Self-Hostable - Deploy to your own Vercel account
- 🔀 Advanced Features - Sorting, pagination, and legacy aliases support
The API is available for free - no setup needed!
# Get all provinces
curl https://konoland-api.vercel.app/province
# Get province by code
curl https://konoland-api.vercel.app/province/11
# Search by name
curl https://konoland-api.vercel.app/province?name=Jawa- Fork this repository on GitHub
- Create a Supabase project at supabase.com (free tier works)
- Get your database URL from Supabase Settings → Database
- Deploy to Vercel:
- Go to vercel.com/new
- Import your forked repository
- Add environment variable:
DATABASE_URL(your Supabase connection string) - Click Deploy
- Import data (see Database Setup below)
List endpoints (paginated) return:
{
"data": [
{
"code": "11",
"province": "Aceh"
},
...
],
"meta": {
"limit": 10,
"page": 1,
"total": 37
}
}Detail endpoints (by code) return the entity directly:
{
"code": "11",
"province": "Aceh"
}| Endpoint | Description | Example |
|---|---|---|
GET /province |
List provinces (paginated) | /province?page=1&limit=10 |
GET /province/:code |
Get province by code | /province/11 |
GET /regency |
List regencies (paginated) | /regency?provinceCode=11 |
GET /regency/:code |
Get regency by code | /regency/1101 |
GET /district |
List districts (paginated) | /district?regencyCode=1101 |
GET /district/:code |
Get district by code | /district/110101 |
GET /village |
List villages (paginated) | /village?districtCode=110101 |
GET /village/:code |
Get village by code | /village/1101012001 |
All list endpoints support:
page- Page number (default: 1)limit- Items per page (default: 10)name- Search by name (partial match)code- Filter by code (returns entity directly)sortBy- Field to sort by (optional, defaults tocode)sortDirection- Sort direction:ASCorDESC(default:ASC)provinceCode- Filter by parent provinceregencyCode- Filter by parent regencydistrictCode- Filter by parent district
For compatibility with wilayah-nusantara API, the following legacy parameter names are also supported:
| Legacy Parameter | Current Parameter | Endpoint |
|---|---|---|
provinsiCode |
provinceCode |
/regency |
kabkotCode |
regencyCode |
/district |
kecamatanCode |
districtCode |
/village |
Example:
# Both work the same way:
GET /regency?provinceCode=11 # Current API
GET /regency?provinsiCode=11 # Legacy (wilayah-nusantara)
GET /district?regencyCode=1101 # Current API
GET /district?kabkotCode=1101 # Legacy (wilayah-nusantara)
GET /village?districtCode=110101 # Current API
GET /village?kecamatanCode=110101 # Legacy (wilayah-nusantara)Each endpoint supports different sort fields:
- Provinces:
code,province - Regencies:
code,regency,provinceCode,type - Districts:
code,district,regencyCode - Villages:
code,village,districtCode,postalCode
Examples:
# Sort provinces by name in ascending order
GET /province?sortBy=province&sortDirection=ASC
# Sort regencies by name in descending order
GET /regency?provinceCode=11&sortBy=regency&sortDirection=DESC
# Default behavior (no sorting params = sort by code ASC)
GET /province- Go to supabase.com and create a project
- Get your connection string from Settings → Database
- Use Connection Pooling URL for Vercel (port 6543)
Option A: Use the SQL file (Recommended)
- For default 'public' schema: Copy and paste the contents of
database-schema.sqlinto Supabase SQL Editor, then click Run. - For custom schema: Use
database-schema-with-schema.sqlinstead. ReplaceYOUR_SCHEMA_NAMEwith your actual schema name (e.g., 'konoland-schema'), then run it.
Option B: Copy SQL manually
Run this SQL in Supabase SQL Editor:
-- Create provinces table
CREATE TABLE provinces (
code BIGINT PRIMARY KEY,
province VARCHAR(255) NOT NULL
);
-- Create regencies table
CREATE TABLE regencies (
code BIGINT PRIMARY KEY,
province_code BIGINT NOT NULL,
regency VARCHAR(255) NOT NULL,
type VARCHAR(20) NOT NULL CHECK (type IN ('Kota', 'Kabupaten')),
FOREIGN KEY (province_code) REFERENCES provinces(code)
);
-- Create districts table
CREATE TABLE districts (
code BIGINT PRIMARY KEY,
regency_code BIGINT NOT NULL,
district VARCHAR(255) NOT NULL,
FOREIGN KEY (regency_code) REFERENCES regencies(code)
);
CREATE INDEX idx_districts_regency_code ON districts(regency_code);
-- Create villages table
CREATE TABLE villages (
code BIGINT PRIMARY KEY,
district_code BIGINT NOT NULL,
village VARCHAR(255) NOT NULL,
postal_code VARCHAR(10) NOT NULL,
FOREIGN KEY (district_code) REFERENCES districts(code)
);CSV files are in data/2025/ directory - ready to import, columns match database exactly!
- Go to Supabase Table Editor
- Import in this order (important for foreign keys!):
provinces.csv→provincestableregencies.csv→regenciestabledistricts.csv→districtstablevillages.csv→villagestable
- For each file:
- Select the table
- Click Insert → Import data from CSV
- Upload the file
- ✅ Columns will auto-map correctly (no manual mapping needed!)
CSV Files (columns match database exactly):
provinces.csv:code, province(38 provinces)regencies.csv:code, province_code, regency, type(514 regencies)districts.csv:code, regency_code, district(7,285 districts)villages.csv:code, district_code, village, postal_code(83,762 villages with 100% postal codes)
In Vercel dashboard (or .env file for local development), add:
DATABASE_URL- Your Supabase Connection Pooling URLNODE_ENV=production(ordevelopmentfor local)APP_ENV=production(ordevelopmentfor local)DATABASE_SCHEMA(Optional) - Specify a custom schema name if you're not using the default 'public' schema
Example .env file:
DATABASE_URL=postgresql://postgres.[PROJECT-REF]:[PASSWORD]@aws-0-[REGION].pooler.supabase.com:6543/postgres?pgbouncer=true
NODE_ENV=production
APP_ENV=production
DATABASE_SCHEMA=konoland-schema # Optional: only if using a custom schema- Node.js 18+
- npm
- Supabase account (for database)
# Clone repository
git clone https://github.com/leonurium/konoland-api.git
cd konoland-api
# Install dependencies
npm install
# Create .env file
cp .env.example .env
# Update .env with your Supabase credentials
# DATABASE_URL=postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
# Start development server
npm run start:dev
# API will be available at http://localhost:3000npm run start:dev # Start with hot reload
npm run build # Build for production
npm run start:prod # Start production server
npm run lint # Run linter2025 Data (Kepmendagri No 300.2.2-2138 Tahun 2025):
- 38 Provinces (Provinsi) - Including 4 new Papua provinces
- 514 Regencies (Kota/Kabupaten)
- 7,285 Districts (Kecamatan)
- 83,762 Villages (Desa/Kelurahan) - With 100% postal code coverage
Data is accurate as of 2025 and follows official Indonesian government structure.
What's New in 2025:
- 4 new provinces in Papua region (codes 93-96)
- Complete postal code data for all villages
- Updated administrative boundaries
This API is 100% backward compatible with the original Wilayah Nusantara API:
- ✅ Same response format
- ✅ Same endpoints
- ✅ Same query parameters
- ✅ Same error messages
- ✅ Drop-in replacement
Existing applications can switch to this API without any code changes!
-
Push to GitHub:
git init git add . git commit -m "Initial commit" git remote add origin https://github.com/leonurium/konoland-api.git git push -u origin main
-
Deploy on Vercel:
- Go to vercel.com/new
- Import your repository
- Add environment variables (see Database Setup)
- Click Deploy
-
Your API is live! 🎉
-
Update Data to 2025✅ DONE (January 2026) -
Integrate Postal Codes✅ DONE (100% coverage) - Add caching layer for improved performance
- Add API rate limiting
Contributions are welcome!
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
See CONTRIBUTING.md for details.
ISC License - See LICENSE file
- Wilayah Nusantara API by @theodevoid - Original inspiration
- Kementerian Dalam Negeri (Kemendagri) - Official 2025 data
- Supabase for free PostgreSQL hosting
- Vercel for free serverless hosting
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ for the Indonesian developer community
Konoha Land API - Free Indonesian Administrative Regions API
⭐ Star this repo if you find it useful!
