API Documentation

A free JSON API, no sign-up or API key required, open CORS for any origin. Use it to look up Vietnam's province/district/ward administrative merger data after the 07/01/2025 reorganization.

Base URL

https://sapnhap.d4t0.com/api/v1

Endpoints

GET /api/v1/provinces

Returns the list of all 63 former provinces/cities, with district and ward counts for each.

Example request

curl https://sapnhap.d4t0.com/api/v1/provinces

Example response

[
  { "name": "Thành phố Hà Nội", "slug": "ha-noi", "districtCount": 30, "wardCount": 794 },
  { "name": "Tỉnh Hà Giang", "slug": "ha-giang", "districtCount": 11, "wardCount": 196 },
  ...
]
GET /api/v1/provinces/{slug}

Returns the old districts/wards of a province, with the matching new province/ward after the merger. Get slug from the /api/v1/provinces endpoint above.

Example request

curl https://sapnhap.d4t0.com/api/v1/provinces/da-nang

Example response

[
  {
    "district": "Quận Hải Châu",
    "wards": [
      { "ward": "Phường Thanh Bình", "newProvince": "Thành phố Đà Nẵng", "newWard": "Phường Hải Châu" },
      ...
    ]
  },
  ...
]
GET /api/v1/lookup

Look up a single old address (Province, District, Ward) and get back the matching new address.

ParamRequiredDescription
provinceYesOld province name (e.g. "Thành phố Đà Nẵng") or slug (e.g. "da-nang")
districtYesOld district name, e.g. "Quận Hải Châu"
wardYesOld ward name, e.g. "Phường Thanh Bình"

Example request

curl "https://sapnhap.d4t0.com/api/v1/lookup?province=da-nang&district=Qu%E1%BA%ADn%20H%E1%BA%A3i%20Ch%C3%A2u&ward=Ph%C6%B0%E1%BB%9Dng%20Thanh%20B%C3%ACnh"

Example response

{
  "old": {
    "province": "Thành phố Đà Nẵng",
    "district": "Quận Hải Châu",
    "ward": "Phường Thanh Bình"
  },
  "new": {
    "province": "Thành phố Đà Nẵng",
    "ward": "Phường Hải Châu"
  }
}

On no match (404)

{ "error": "Ward not found: ..." }

Some old wards were split across multiple new units during the merger. In that case new.ward is the recommended new unit (main area/population), and the response includes new.alternativeWards listing the other new units that part of the old ward also belongs to.

Example response for a split ward

{
  "old": {
    "province": "Thành phố Hà Nội",
    "district": "Huyện Thanh Trì",
    "ward": "Thị trấn Văn Điển"
  },
  "new": {
    "province": "Thành phố Hà Nội",
    "ward": "Xã Thanh Trì",
    "alternativeWards": ["Phường Hoàng Liệt", "Xã Đại Thanh"]
  }
}

Rate limiting

To prevent abuse and DDoS traffic, each IP address is limited by two parallel thresholds (applies to all of /api/v1/*). Exceeding either returns 429 Too Many Requests with a Retry-After header.

TypeThresholdPurpose
Burst30 requests / 10sBlocks sudden floods (DDoS/bot signature)
Sustained300 requests / 60sBlocks prolonged abuse, still generous for normal integrations

Example response when rate limited (429)

{ "error": "Too many requests, slow down." }

Limits & notes

The API is free, no sign-up required. Responses are cached at Cloudflare's edge for fast delivery. Data is compiled from national administrative data sources; for important legal purposes, double-check with your local authority's official decision.