GoGoDuk

GET /v1/pois

Search Vietnam POIs (points of interest) in a bounding box, ranked by distance.

Returns a GeoJSON FeatureCollection of points of interest (restaurants, cafes, ATMs, hospitals, and more) inside a bounding box, ordered by distance to near (or to the center of the box). Use it for nearby search, category map layers, and local discovery in Vietnam.

Required scope: places:read

This page also covers the two companion endpoints: /v1/pois/tiles/{z}/{x}/{y} (vector tiles for map layers) and /v1/pois/{placeId} (full detail for a single place).

Request

GET /v1/pois?bbox=106.69,10.76,106.71,10.78&near=106.70,10.77&category=restaurant,cafe&limit=5
X-API-Key: gdk_live_xxxxxxxxxxxxxxxxxxxxxxxx
curl -G "https://api.gogoduk.com/v1/pois" \
-H "X-API-Key: $GOGODUK_API_KEY" \
--data-urlencode "bbox=106.69,10.76,106.71,10.78" \
--data-urlencode "near=106.70,10.77" \
--data-urlencode "category=restaurant,cafe" \
--data-urlencode "limit=5"

Query parameters

NameRequiredDescription
bboxyesBounding box as minLng,minLat,maxLng,maxLat (e.g. 106.69,10.76,106.71,10.78).
nearnolng,lat used as the distance-ranking center. Defaults to the center of bbox.
limitnoNumber of POIs to return, 110. Default 5.
categorynoComma-separated category ids (matches any-of). See Categories.
min_ratingnoOnly return POIs with a rating ≥ this value (05).
open_nownotrue to return only POIs marked open at request time.

Response

A GeoJSON FeatureCollection. List features carry light properties to keep responses compact — place_id, name, and primary_type. Fetch the rest with the detail endpoint.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [106.701, 10.772] },
      "properties": {
        "place_id": "poi_abc123",
        "name": "Example Restaurant",
        "primary_type": "restaurant"
      }
    }
  ]
}

Response fields

FieldTypeDescription
typestringAlways FeatureCollection.
features[]arrayPOIs ordered by distance (nearest first).
features[].geometry.coordinatesarray[lng, lat] of the POI.
features[].properties.place_idstringStable POI identifier.
features[].properties.namestringDisplay name.
features[].properties.primary_typestringPrimary category id (e.g. restaurant).

Categories

The category filter accepts one or more category ids (comma-separated, any-of). Common ids include:

restaurant, cafe, bar, bakery, supermarket, convenience_store, shopping_mall, hospital, pharmacy, bank, atm, gas_station, lodging, school, university, post_office, parking.

Fetch the full list with display labels (English + Vietnamese) from GET /v1/categories.

POI vector tiles

For map layers that render many POIs at once, use Mapbox Vector Tiles instead of repeatedly calling /v1/pois:

GET /v1/pois/tiles/{z}/{x}/{y}
X-API-Key: gdk_live_xxxxxxxxxxxxxxxxxxxxxxxx

The map renderer requests tiles by zoom (z) and tile coordinates (x/y). Each tile response also issues a short-lived X-POI-Token per feature, which the detail endpoint requires.

Required scope: places:read

POI detail

Fetch full details for a single POI by place_id:

GET /v1/pois/{placeId}
X-API-Key: gdk_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-POI-Token: <token from the tile response>

The X-POI-Token header is required — it is the per-feature token returned in vector-tile responses. The result is a single object with the full property set:

{
  "result": {
    "place_id": "poi_abc123",
    "name": "Example Restaurant",
    "primary_type": "restaurant",
    "formatted_address": "12 Nguyễn Huệ, Bến Nghé, Quận 1",
    "city": "Hồ Chí Minh",
    "district": "Quận 1",
    "rating": 4.5,
    "user_rating_count": 120,
    "opening_hours": { "...": "..." },
    "phone": "028 1234 5678",
    "website": "https://example.com",
    "price_level": "PRICE_LEVEL_MODERATE"
  }
}

Optional fields (rating, user_rating_count, opening_hours, phone, international_phone, website, price_level) are only present when data exists, so check for a key before reading it.

Required scope: places:read

Common errors

  • 400 INVALID_BBOXbbox is not in minLng,minLat,maxLng,maxLat form.
  • 400bbox min values are not less than max values.
  • 401 INVALID_API_KEY — key not recognized.
  • 403 INSUFFICIENT_SCOPE — key is missing places:read.
  • 404/v1/pois/{placeId} — no POI for that place_id.
  • 429 RATE_LIMIT_MINUTE — back off using the retry_after field.

On this page