Cambodia Flag Cambodia Geography API

Fast Free & Open API for Cambodia Geography

An open API for Cambodia geography data providing complete 4-tier administrative hierarchy (Provinces, Districts, Communes, Villages), 100% free to use for everyone, with ultra-fast sub-millisecond response times.

$ curl http://localhost:3000/api/admin/provinces
25

រាជធានី / ខេត្ត

210

ខណ្ឌ / ក្រុង / ស្រុក

1,661

សង្កាត់ / ឃុំ

14,576

ភូមិ

Interactive Playground

Test Cambodia Geographic Endpoints

Cascading Address Selector

< 1ms
1
Province / Capital (រាជធានី / ខេត្ត) Loading...
2
District / Khan / Krong (ខណ្ឌ / ក្រុង / ស្រុក) Filtered
3
Commune / Sangkat (សង្កាត់ / ឃុំ) Filtered
4
Village (ភូមិ) Filtered
Resolved Hierarchy Path
API Response Payload
GET /api/admin/provinces
// Connecting to OpenGeo Cambodia API...
Project Purpose & Pillars

Open API for Cambodia Geography Data

Built to solve Cambodia's address and geographic data resolution challenges through three foundational pillars: complete 4-tier hierarchy, 100% free accessibility, and ultra-fast sub-millisecond response times.

Pillar 1

Administrative Hierarchy

Complete official coverage: 25 Provinces, 210 Districts, 1,661 Communes, and 14,576 Villages with standardized administrative codes.

16,472 Total Entities
Pillar 2

100% Free to Use

Zero cost, zero API keys, no subscriptions, and no paywalls. Free for developers, startups, logistics, fintech KYC, government forms, and NGOs under the MIT license.

MIT License • Open Access
Pillar 3

Fast Response Time

Sub-1ms latency. Pre-indexed RAM architecture serves cascading dropdowns and address lookups in under 1 millisecond with zero database overhead.

< 1ms In-Memory Speed
Feature

Bilingual & GPS Geocoder

Full support for native Khmer script (អក្សរខ្មែរ) and Latin Romanization with smart OpenStreetMap GPS reverse geocoding into 4-tier addresses.

Khmer + Latin + OSM
Kingdom of Cambodia

Cambodia 4-Tier Administrative System

The Kingdom of Cambodia organizes territorial governance into four cascading administrative levels. OpenGeo Cambodia models each tier with standard government identification codes sourced from the official Ministry of Economy and Finance Open Data Portal (data.mef.gov.kh):

Tier 1 • ២៥ 2-Digit Code

Province & Capital

រាជធានី និង ខេត្ត (Khaet / Reach Theani)

24 Provinces and 1 Autonomous Municipality (Phnom Penh Capital). Codes range from 01 to 25.

Tier 2 • ២១០ 4-Digit Code

District, Khan & Krong

ខណ្ឌ ក្រុង និង ស្រុក (Srok / Krong / Khan)

162 Rural Districts (ស្រុក), 34 Municipalities (ក្រុង), and 14 Urban Khans (ខណ្ឌ) in Phnom Penh.

Tier 3 • ១,៦៦១ 6-Digit Code

Commune & Sangkat

សង្កាត់ និង ឃុំ (Khum / Sangkat)

1,405 Rural Communes (ឃុំ) and 256 Urban Quarters / Sangkats (សង្កាត់).

Tier 4 • ១៤,៥៧៦ 8-Digit Code

Villages

ភូមិ (Phum)

Foundational human settlements across rural and urban Cambodia, mapped directly to parent communes.

Selected Cambodian Provinces & Geographic Codes

Quick reference table for major economic and cultural provincial centers.

View all 25 provinces JSON
Code Province Name (English) ឈ្មោះជាភាសាខ្មែរ Type Districts
12 Phnom Penh រាជធានីភ្នំពេញ Autonomous Municipality (Capital) 14 Khans
17 Siem Reap ខេត្តសៀមរាប Province (Angkor Wat Hub) 12 Districts
02 Battambang ខេត្តបាត់ដំបង Province (Northwest Agricultural Hub) 14 Districts
18 Preah Sihanouk ខេត្តព្រះសីហនុ Coastal Province (Deep Sea Port) 5 Districts
08 Kandal ខេត្តកណ្តាល Province (Metropolitan Ring) 11 Districts
07 Kampot ខេត្តកំពត Coastal Province (Agriculture & Tourism) 8 Districts
Integration Guide

Integrate in 30 Seconds

OpenGeo Cambodia is a frictionless REST API with CORS enabled for all origins, zero API keys required, and standard JSON responses.

1 / 10
JavaScript / TypeScript (Fetch API)
// 1. Cascading lookup: Fetch all districts in Phnom Penh (Province Code: 12)
const res = await fetch('https://opengeo-cambodia.pphat.me/api/admin/provinces/12/districts');
const { data: districts } = await res.json();
console.log('Districts found:', districts.map(d => `${d.code} - ${d.name_km} (${d.name_en})`));

// 2. Reverse geocode GPS coordinates to 4-tier Cambodian address
const geoRes = await fetch('https://opengeo-cambodia.pphat.me/api/geocode/reverse?lat=11.5564&lon=104.9282');
const location = await geoRes.json();
console.log(`${location.province} > ${location.district} > ${location.commune}`);

// 3. Fast bilingual search (Khmer script & Latin romanization)
const searchRes = await fetch('https://opengeo-cambodia.pphat.me/api/admin/search?q=' + encodeURIComponent('វត្តភ្នំ'));
const searchData = await searchRes.json();
console.log('Search matches:', searchData.data);
Sub-1ms Latency • CORS Enabled (All Origins)
Native browser fetch / Zero external dependencies
Python (Requests / HTTPX)
import requests

BASE_URL = "https://opengeo-cambodia.pphat.me"

# 1. Fuzzy search for administrative entities (Khmer or English)
response = requests.get(f"{BASE_URL}/api/admin/search", params={"q": "Doun Penh"})
matches = response.json()
print(f"Found {len(matches.get('data', []))} administrative records")

# 2. Complete 4-tier hierarchy trace for Sangkat Phsar Thmei 1 (code 120101)
hierarchy = requests.get(f"{BASE_URL}/api/admin/hierarchy/120101").json()
print("Administrative Path:", hierarchy.get("path"))

# 3. GPS Reverse Geocoding (Wat Phnom: 11.5761, 104.9230)
geo = requests.get(f"{BASE_URL}/api/geocode/reverse", params={"lat": 11.5761, "lon": 104.9230}).json()
print(f"Address: {geo.get('commune')}, {geo.get('district')}, {geo.get('province')}")
Fast In-Memory Resolution • JSON API
FastAPI, Django, Flask & Jupyter compatible
cURL / Shell CLI
# 1. Fetch all 25 Provinces in Cambodia (<1ms edge response)
curl -s "https://opengeo-cambodia.pphat.me/api/admin/provinces" \
  | jq '.data[] | {code, name_km, name_en}'

# 2. Reverse geocode GPS coordinates (Independence Monument, Phnom Penh)
curl -s "https://opengeo-cambodia.pphat.me/api/geocode/reverse?lat=11.5564&lon=104.9282" \
  | jq '{province: .province, district: .district, commune: .commune}'

# 3. Bilingual administrative search in Khmer script
curl -s -G "https://opengeo-cambodia.pphat.me/api/admin/search" \
  --data-urlencode "q=សៀមរាប" | jq '.data[0]'
Zero Auth Required • Direct Terminal Access
Perfect for dev pipelines & microservices
PHP (Vanilla / Laravel / WordPress)
<?php
// 1. Fetch all districts of Siem Reap province (Province Code: 17)
$url = 'https://opengeo-cambodia.pphat.me/api/admin/provinces/17/districts';
$response = file_get_contents($url);
$districts = json_decode($response, true)['data'] ?? [];

foreach ($districts as $district) {
    echo "{$district['code']}: {$district['name_km']} ({$district['name_en']})\n";
}

// 2. Reverse geocode GPS coordinates to Cambodian Address
$geoUrl = 'https://opengeo-cambodia.pphat.me/api/geocode/reverse?lat=11.5564&lon=104.9282';
$geo = json_decode(file_get_contents($geoUrl), true);
echo "Location: {$geo['commune']}, {$geo['district']}, {$geo['province']}\n";
Simple Integration • No SDK Required
Works with Laravel Http Client, Guzzle, or file_get_contents
Go (Golang net/http)
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type ApiResponse struct {
    Success bool             `json:"success"`
    Data    []map[string]any `json:"data"`
}

func main() {
    // 1. Fetch Cambodia 25 Provinces (<1ms in-memory cache)
    resp, err := http.Get("https://opengeo-cambodia.pphat.me/api/admin/provinces")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var result ApiResponse
    if err := json.NewDecoder(resp.Body).Decode(&result); err == nil {
        fmt.Printf("Loaded %d provinces successfully\n", len(result.Data))
    }
}
Ultra High Throughput • Type-Safe
Standard library only / Zero 3rd-party dependencies
Dart (Mobile Apps)
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<void> main() async {
  const baseUrl = 'https://opengeo-cambodia.pphat.me';

  // 1. Fetch Cambodia 25 Provinces for mobile address dropdown
  final res = await http.get(Uri.parse('$baseUrl/api/admin/provinces'));
  if (res.statusCode == 200) {
    final Map<String, dynamic> body = jsonDecode(res.body);
    final List provinces = body['data'];
    print('Loaded ${provinces.length} provinces successfully');
  }

  // 2. Reverse Geocode GPS coordinates (Phnom Penh)
  final geoRes = await http.get(Uri.parse(
    '$baseUrl/api/geocode/reverse?lat=11.5564&lon=104.9282'
  ));
  final location = jsonDecode(geoRes.body);
  print('Address: ${location['province']} > ${location['district']} > ${location['commune']}');
}
Mobile-Optimized Payload • iOS & Android Ready
Perfect for Flutter delivery & e-commerce checkout
Kotlin (Android / OkHttp)
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject

val client = OkHttpClient()
val baseUrl = "https://opengeo-cambodia.pphat.me"

// 1. Cascading lookup: Phnom Penh districts (Code: 12)
val request = Request.Builder()
    .url("$baseUrl/api/admin/provinces/12/districts")
    .build()

client.newCall(request).execute().use { response ->
    val json = JSONObject(response.body!!.string())
    val districts = json.getJSONArray("data")
    println("Found ${districts.length()} districts in Phnom Penh")
}

// 2. Reverse Geocode GPS coordinates (Wat Phnom: 11.5761, 104.9230)
val geoRequest = Request.Builder()
    .url("$baseUrl/api/geocode/reverse?lat=11.5761&lon=104.9230")
    .build()
val geo = JSONObject(client.newCall(geoRequest).execute().body!!.string())
println("Location: ${geo.optString("commune")}, ${geo.optString("district")}, ${geo.optString("province")}")
Sub-1ms In-Memory Resolution • Native Android
Works with Coroutines, Retrofit, Jetpack Compose, & OkHttp
.NET (HttpClient & System.Text.Json)
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

using var client = new HttpClient();
const string baseUrl = "https://opengeo-cambodia.pphat.me";

// 1. Fetch all 25 Provinces in Cambodia (<1ms response)
var json = await client.GetStringAsync($"{baseUrl}/api/admin/provinces");
using var doc = JsonDocument.Parse(json);
var provinces = doc.RootElement.GetProperty("data");

foreach (var p in provinces.EnumerateArray())
{
    Console.WriteLine($"{p.GetProperty("code")}: {p.GetProperty("name_km")} ({p.GetProperty("name_en")})");
}

// 2. Reverse Geocode GPS to Cambodian Address
var geoJson = await client.GetStringAsync($"{baseUrl}/api/geocode/reverse?lat=11.5564&lon=104.9282");
using var geoDoc = JsonDocument.Parse(geoJson);
Console.WriteLine($"Province: {geoDoc.RootElement.GetProperty("province")}");
Enterprise Ready • Strict Types
ASP.NET Core, Blazor, MAUI, & Azure Cloud compatible
Swift (iOS / macOS / URLSession)
import Foundation

let baseUrl = "https://opengeo-cambodia.pphat.me"

// 1. Fetch 25 Cambodia Provinces asynchronously
guard let url = URL(string: "\(baseUrl)/api/admin/provinces") else { return }
let (data, _) = try await URLSession.shared.data(from: url)

if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
   let provinces = json["data"] as? [[String: Any]] {
    print("Loaded \(provinces.count) Cambodian provinces")
}

// 2. Reverse Geocode GPS coordinates (CoreLocation integration)
let geoUrl = URL(string: "\(baseUrl)/api/geocode/reverse?lat=11.5564&lon=104.9282")!
let (geoData, _) = try await URLSession.shared.data(from: geoUrl)
if let loc = try? JSONSerialization.jsonObject(with: geoData) as? [String: Any] {
    print("\(loc["province"] ?? "") > \(loc["district"] ?? "")")
}
Swift Concurrency • Native Apple Frameworks
Async/Await ready for SwiftUI, UIKit & CoreLocation apps
Rust (reqwest & serde_json)
use reqwest;
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let base_url = "https://opengeo-cambodia.pphat.me";

    // 1. Fetch all 25 Provinces (<1ms edge response)
    let resp: Value = reqwest::get(format!("{}/api/admin/provinces", base_url))
        .await?
        .json()
        .await?;

    if let Some(provinces) = resp["data"].as_array() {
        println!("Loaded {} provinces successfully", provinces.len());
    }

    // 2. Reverse Geocode Coordinates
    let geo: Value = reqwest::get(format!("{}/api/geocode/reverse?lat=11.5564&lon=104.9282", base_url))
        .await?
        .json()
        .await?;

    println!("Location: {} / {}", geo["district"], geo["province"]);
    Ok(())
}
Memory Safe & Concurrent • Zero Overhead
Actix-web, Axum & Tokio high-throughput microservices
Knowledge Base

Frequently Asked Questions

Common questions regarding Cambodia administrative boundaries, geography queries, and OpenGeo API usage.

01. What is OpenGeo Cambodia and its purpose?

OpenGeo Cambodia is an open API for Cambodia geography data designed around three core pillars:

  1. Administrative Hierarchy: Complete coverage across all 4 official tiers (25 Provinces, 210 Districts, 1,661 Communes, and 14,576 Villages).
  2. Allow users to use for free: 100% free and open-access under the MIT license with zero API keys and no paywalls.
  3. Provide fast response time: Sub-1ms (<1ms) in-memory query speed with zero database overhead.
02. How many provinces and administrative tiers exist in Cambodia?
Cambodia is divided into 4 official administrative tiers: 1) Tier 1 has 25 Provinces (ខេត្ត) including the capital municipality Phnom Penh (រាជធានី); 2) Tier 2 has 210 Districts (ស្រុក), Municipalities (ក្រុង), and Khans (ខណ្ឌ); 3) Tier 3 has 1,661 Communes (ឃុំ) and Sangkats (សង្កាត់); and 4) Tier 4 has 14,576 Villages (ភូមិ).
03. Does OpenGeo Cambodia support both Khmer script and English Romanization?
Yes. Every administrative entity includes its official Khmer name in Khmer script (e.g., រាជធានីភ្នំពេញ, ដូនពេញ), standardized Latin English transliteration (e.g., Phnom Penh, Doun Penh), and official administrative code. The search endpoint matches both interchangeably.
04. How fast is the OpenGeo Cambodia cascading lookup?
OpenGeo Cambodia delivers sub-1ms (<1ms) response times for administrative lookups by leveraging an optimized in-memory indexed data store and edge-ready Cloudflare Workers / Node.js architecture.
05. How does reverse geocoding work in Cambodia with OpenGeo?
By providing latitude and longitude coordinates (e.g. 11.5564, 104.9282), OpenGeo queries OpenStreetMap Nominatim and normalizes the raw GPS location into the standardized 4-tier Cambodian administrative hierarchy (Province → District → Commune → Village).
06. Is OpenGeo Cambodia free to use for commercial projects?
Yes, OpenGeo Cambodia is 100% free and open-source under the MIT license for developers, fintech applications, delivery logistics, NGOs, and businesses across Cambodia.
07. Where is the Cambodia geography and administrative data sourced from?

All Cambodian geographic and administrative datasets (covering all 25 Provinces, 210 Districts, 1,661 Communes, and 14,576 Villages) are officially sourced from the Ministry of Economy and Finance (MEF) Open Data Portal at https://data.mef.gov.kh/.

Geospatial coordinates and reverse geocoding boundaries are cross-referenced with OpenStreetMap and Nominatim data.