Vietnam street names by ward API
List and search the street names (đường, phố, ngõ, hẻm) of each new Vietnamese ward and province from OpenStreetMap, accent-insensitive.
Street-level address data for the 34 provinces and 3,321 phường / xã / đặc khu in force since 1/7/2025. ward=<code or name> lists the streets of one ward (streets first, then ngõ / hẻm / kiệt), province=<code or name> lists every street of a province with the wards it runs through, and q searches by name: without accents or case (le loi finds “Đường Lê Lợi”), ignoring the generic word (đường, phố, ngõ, hẻm), with exact diacritics ranked first. q alone searches the whole country and returns, for each name, the provinces where it exists. Filter by type (street, alley, bridge, road for numbered roads such as QL1A), page with limit and offset.
Each street comes with its OpenStreetMap road class, its approximate length in the ward, a representative point (lat / lng) and a link to an OSM way. Data comes from OpenStreetMap (Geofabrik extract for Vietnam), rebuilt monthly: named roads are placed in wards by point-in-polygon on the same simplified boundaries as /v1/vn-geo, segment by segment, so a long road appears in every ward it crosses, and a road that only touches a ward is left out.
Coverage is as good as OpenStreetMap: dense in Hà Nội, TP.HCM, Đà Nẵng and other cities (about 118,000 ward / street pairs in total), thin in rural and mountainous communes where many roads have no name in OSM. Data © OpenStreetMap contributors under the ODbL 1.0: every response carries the attribution, and a redistributed copy of the list must keep it and stay under the ODbL.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
ward | query | string | no | Ward / commune: 5-digit code (e.g. 00070) or name (Phường Hoàn Kiếm, add province when the name exists in several provinces). Also as a path: /v1/vn-streets/00070. | |
province | query | string | no | Province code (01, 79) or name (Hà Nội, hcm). Alone: every street of the province with its wards. | |
q | query | string | no | Name to search, with or without accents (max 100 characters). Alone: nationwide search. | |
type | query | string | no | all | street, alley (ngõ, ngách, hẻm, kiệt), bridge, road (numbered roads) or all. |
limit | query | number | no | 1000 | Maximum results (1–5000; default 50 with q, 1000 otherwise). |
offset | query | number | no | 0 | Skip this many results (paging). |
Example
curl "https://apibox.io.vn/v1/vn-streets?ward=00070&q=hang&limit=3" \
-H "Authorization: Bearer YOUR_API_KEY"const res = await fetch('https://apibox.io.vn/v1/vn-streets?ward=00070&q=hang&limit=3', {
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-streets?ward=00070&q=hang&limit=3",
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/vn-streets?ward=00070&q=hang&limit=3');
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
{
"ward": {
"code": "00070",
"name": "Phường Hoàn Kiếm",
"province_code": "01",
"province": "Thành phố Hà Nội"
},
"total": 55,
"offset": 0,
"count": 3,
"streets": [
{
"name": "Hàng Cân",
"name_ascii": "hang can",
"type": "street",
"highway": "tertiary",
"length_m": 157,
"lat": 21.03465,
"lng": 105.84967,
"osm_way": "https://www.openstreetmap.org/way/28102774"
},
{
"name": "Phố Hàng Bè",
"name_ascii": "pho hang be",
"type": "street",
"highway": "residential",
"length_m": 177,
"lat": 21.03264,
"lng": 105.85382,
"osm_way": "https://www.openstreetmap.org/way/399591853"
},
{
"name": "Phố Hàng Bồ",
"name_ascii": "pho hang bo",
"type": "street",
"highway": "residential",
"length_m": 285,
"lat": 21.03382,
"lng": 105.84815,
"osm_way": "https://www.openstreetmap.org/way/28103110"
}
],
"attribution": "© OpenStreetMap contributors",
"licence": "ODbL-1.0",
"licence_url": "https://www.openstreetmap.org/copyright",
"licence_note": "Street data © OpenStreetMap contributors, available under the Open Database License. This list is a derived database: if you redistribute it (or a substantial extract), credit OpenStreetMap and share it under the ODbL.",
"coverage_note": "Only streets that carry a name in OpenStreetMap are listed; coverage is good in cities and incomplete in rural and mountainous areas. Wards are assigned from simplified boundaries, so streets on a ward border can appear in both wards.",
"data": {
"version": "20261111",
"osm_timestamp": "2026-11-09T21:22:17.000Z",
"built_at": "2026-11-11T03:01:14.154Z",
"admin_version": "v5.2.0",
"refresh": "monthly"
}
}
Use cases
- Street autocomplete in checkout and delivery address forms
- Validate that a street exists in the selected new ward
- Build ward-level street pickers for CRM and logistics apps
- Map old addresses to the new wards by street name
FAQ
Why is my street missing?
Only roads that have a name in OpenStreetMap are listed. You can add the name on openstreetmap.org; it appears here after the next monthly rebuild.
Why does a street appear in two wards?
Long streets cross several wards and are listed in each one, with the length inside that ward. Streets exactly on a border may appear on both sides.
Can I download and reuse the list?
Yes, under the ODbL: credit “© OpenStreetMap contributors” and share a redistributed copy of the database under the same licence.
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.