Coordinates to Ward (Vietnam) API
Turn latitude / longitude into the current (post-07/2025) province and phường / xã of Vietnam with their codes; batch up to 1000 points, ward boundaries.
Send lat and lng (WGS 84, as given by phones and GPS) and get the province (34 units) and the phường / xã / đặc khu (3,321 units) that contain the point after the 1 July 2025 reorganisation, with the same GSO codes, names and postal codes as /v1/vn-provinces. distance=1 adds the distance to the ward boundary; ward=<code> with a point tells whether the point is inside that ward (geofencing, attendance check-in), and ward=<code> alone returns its bounding box, centroid, area and, with geometry=1, its simplified boundary as GeoJSON.
For batches, POST points as [[lat, lng], …] or [{"lat": …, "lng": …}] (up to 1000 points per request). A point just outside every ward (on a beach, a river bank, a few metres off a simplified edge) is matched to the nearest ward within max_distance metres (default 250) and flagged inside: false with its distance_m; farther away (open sea, neighbouring countries) the answer is found: false with the nearest ward for information.
Boundaries come from the GIS add-on of the open dataset ThangLeQuoc/vietnamese-provinces-database (MIT), derived from the official reference map sapnhap.bando.com.vn, simplified to about 30 m while keeping shared edges consistent (no gaps or overlaps between neighbours). Points within a few dozen metres of a boundary can therefore land in the neighbouring ward: the answer is marked approximate and is not a cadastral or legal determination. No house-number geocoding.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
lat | query|body | number | no | Latitude in decimal degrees (WGS 84). Or latlng=21.0288,105.8525, or the pair in the path /v1/vn-geo/21.0288,105.8525. | |
lng | query|body | number | no | Longitude in decimal degrees (lon also accepted). | |
points | body | array | no | Batch: up to 1000 points as [[lat, lng], …], [{"lat","lng"}] or "lat,lng;lat,lng". | |
ward | query|body | string | no | Ward code (5 digits). With a point: is the point inside this ward? Alone: bbox, centroid, area of the ward. | |
geometry | query|body | boolean | no | false | With ward alone: add the simplified boundary as a GeoJSON MultiPolygon. |
distance | query|body | boolean | no | false | Add boundary_distance_m: distance from the point to the edge of its ward. |
max_distance | query|body | number | no | 250 | Snap points outside every ward to the nearest one within this many metres (0–50000). |
Example
curl "https://apibox.io.vn/v1/vn-geo?lat=10.7725&lng=106.698" \
-H "Authorization: Bearer YOUR_API_KEY"const res = await fetch('https://apibox.io.vn/v1/vn-geo?lat=10.7725&lng=106.698', {
method: 'GET',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
},
});
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://apibox.io.vn/v1/vn-geo?lat=10.7725&lng=106.698",
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/vn-geo?lat=10.7725&lng=106.698');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY'],
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"lat": 10.7725,
"lng": 106.698,
"found": true,
"inside": true,
"province": {
"code": "79",
"name": "Hồ Chí Minh",
"full_name": "Thành phố Hồ Chí Minh"
},
"ward": {
"code": "26743",
"name": "Bến Thành",
"full_name": "Phường Bến Thành",
"type": "Phường",
"type_en": "ward",
"postal_code": "71009"
},
"approximate": true,
"precision_m": 30,
"data": {
"admin_version": "v5.2.0",
"built_at": "2026-11-11",
"legal_basis": "Nghị quyết 202/2025/QH15 (34 provinces) and the UBTVQH resolutions on ward-level units, effective 1/7/2025; latest change in the dataset: 388/NQ-UBTVQH16",
"source": "ThangLeQuoc/vietnamese-provinces-database GIS add-on (MIT), derived from sapnhap.bando.com.vn (NXB Tài nguyên Môi trường và Bản đồ Việt Nam)"
}
}
Use cases
- Fill the new ward and province from a phone GPS position in delivery or field apps
- Check that an employee checks in inside the assigned ward (geofence)
- Convert a table of shop or customer coordinates to the new administrative units
- Draw a ward boundary on a map from its code
FAQ
Are these the new units after 1 July 2025?
Yes: 34 provinces and 3,321 phường / xã / đặc khu, with the codes of /v1/vn-provinces. The data is checked weekly against the latest dataset release.
How precise is it?
Boundaries are simplified to about 30 m; in tests 99.7% of random points match the full-resolution map, the rest are within a few dozen metres of a boundary.
What happens at sea or outside Vietnam?
Points within max_distance (250 m by default) of the coast snap to the nearest ward; farther away found is false and the nearest ward is given with its distance.
Related APIs
JSON Validator
Check JSON syntax with exact line and column of errors, and validate data against a JSON Schema (draft 4, 7, 2019-09 or 2020-12).
{ }JSON Formatter
Pretty print JSON with 0-8 spaces or tabs, minify it, or sort object keys recursively. Syntax errors are reported with line and column.
CSVCSV to JSON
Convert CSV into an array of JSON objects using the header row, with delimiter auto-detection, number and boolean typing, and row-level errors.