{
  "openapi": "3.0.3",
  "info": {
    "title": "GMap Anonymous API",
    "version": "1.0.0",
    "description": "Google Maps data qua endpoint ẩn danh (không API key, không cookie). Suggest, directions, place detail, vector tiles, MapLibre MVT, buildings (OSM), incidents.\n\n**Viewer:** [/demo](/demo) · [/maplibre](/maplibre) · **Console:** [/console](/console)"
  },
  "servers": [{ "url": "/", "description": "same origin" }],
  "tags": [
    { "name": "Search", "description": "Autocomplete & geocoding" },
    { "name": "Directions", "description": "Chỉ đường nhiều tuyến" },
    { "name": "Places", "description": "Chi tiết POI" },
    { "name": "Tiles", "description": "Vector tiles & MapLibre" },
    { "name": "Overlays", "description": "Buildings & incidents" }
  ],
  "paths": {
    "/suggest": {
      "get": {
        "tags": ["Search"],
        "summary": "Autocomplete địa điểm",
        "description": "Trả gợi ý địa điểm kèm toạ độ, FID, place_id.",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string" }, "example": "197 tran phu" },
          { "name": "lat", "in": "query", "schema": { "type": "number" }, "example": 10.7605107, "description": "Viewport bias latitude" },
          { "name": "lng", "in": "query", "schema": { "type": "number" }, "example": 106.6661053 },
          { "name": "zoom", "in": "query", "schema": { "type": "integer" }, "example": 15 },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 5 }, "example": 5 },
          { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "example": "vi" }
        ],
        "responses": { "200": { "description": "Danh sách gợi ý", "content": { "application/json": {} } } }
      }
    },
    "/directions": {
      "get": {
        "tags": ["Directions"],
        "summary": "Chỉ đường A → B",
        "description": "`from`/`to` nhận địa chỉ tự do hoặc \"lat,lng\". Yêu cầu ẩn danh luôn trả tuyến driving.",
        "parameters": [
          { "name": "from", "in": "query", "required": true, "schema": { "type": "string" }, "example": "197 tran phu" },
          { "name": "to", "in": "query", "required": true, "schema": { "type": "string" }, "example": "cho ben thanh" },
          { "name": "mode", "in": "query", "schema": { "type": "string", "enum": ["driving", "motorbike", "walking", "cycling", "transit"], "default": "driving" }, "example": "driving" },
          { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "example": "vi" },
          { "name": "compact", "in": "query", "schema": { "type": "string", "enum": ["0", "1"] }, "description": "1 = bỏ path[] và steps[]", "example": "0" }
        ],
        "responses": { "200": { "description": "Các tuyến đường", "content": { "application/json": {} } } }
      }
    },
    "/place": {
      "get": {
        "tags": ["Places"],
        "summary": "Chi tiết POI (GetEntityDetails)",
        "description": "FID lấy từ nhãn POI trên vector tile hoặc từ /suggest.",
        "parameters": [
          { "name": "fid", "in": "query", "required": true, "schema": { "type": "string" }, "example": "0x31752f3f3129e64d:0x8d6b2d79522c7f30" },
          { "name": "lang", "in": "query", "schema": { "type": "string", "default": "vi" }, "example": "vi" }
        ],
        "responses": { "200": { "description": "Chi tiết địa điểm", "content": { "application/json": {} } } }
      }
    },
    "/vt/{z}/{x}/{y}": {
      "get": {
        "tags": ["Tiles"],
        "summary": "Raw XOR-protobuf vector tile",
        "description": "Bytes tile gốc của Google (còn XOR) — giải mã phía client bằng vectorTile.js.",
        "parameters": [
          { "name": "z", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 15 },
          { "name": "x", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 26092 },
          { "name": "y", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 15398 }
        ],
        "responses": { "200": { "description": "octet-stream", "content": { "application/octet-stream": {} } } }
      }
    },
    "/mvt/{z}/{x}/{y}.pbf": {
      "get": {
        "tags": ["Tiles"],
        "summary": "Mapbox Vector Tile (cho MapLibre)",
        "description": "Tile Google được re-encode thành MVT chuẩn (layers: road / road_label / poi).",
        "parameters": [
          { "name": "z", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 15 },
          { "name": "x", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 26092 },
          { "name": "y", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 15398 }
        ],
        "responses": { "200": { "description": "protobuf", "content": { "application/x-protobuf": {} } } }
      }
    },
    "/tiles.json": {
      "get": { "tags": ["Tiles"], "summary": "TileJSON cho nguồn /mvt", "responses": { "200": { "description": "TileJSON", "content": { "application/json": {} } } } }
    },
    "/style.json": {
      "get": { "tags": ["Tiles"], "summary": "MapLibre style dựng sẵn (keyless)", "responses": { "200": { "description": "MapLibre style", "content": { "application/json": {} } } } }
    },
    "/buildings": {
      "get": {
        "tags": ["Overlays"],
        "summary": "Building footprints (OSM/Overpass)",
        "description": "Rings [[lat,lng],…] — tile Google không có polygon toà nhà.",
        "parameters": [
          { "name": "minLat", "in": "query", "required": true, "schema": { "type": "number" }, "example": 10.7705 },
          { "name": "minLng", "in": "query", "required": true, "schema": { "type": "number" }, "example": 106.695 },
          { "name": "maxLat", "in": "query", "required": true, "schema": { "type": "number" }, "example": 10.7735 },
          { "name": "maxLng", "in": "query", "required": true, "schema": { "type": "number" }, "example": 106.699 }
        ],
        "responses": { "200": { "description": "Rings polygon", "content": { "application/json": {} } } }
      }
    },
    "/incidents": {
      "get": {
        "tags": ["Overlays"],
        "summary": "Traffic incidents / road closures (field 17)",
        "description": "Marker 'tạm đóng' đã geocode qua /maps/preview/place.",
        "parameters": [
          { "name": "minLat", "in": "query", "required": true, "schema": { "type": "number" }, "example": 10.76 },
          { "name": "minLng", "in": "query", "required": true, "schema": { "type": "number" }, "example": 106.68 },
          { "name": "maxLat", "in": "query", "required": true, "schema": { "type": "number" }, "example": 10.79 },
          { "name": "maxLng", "in": "query", "required": true, "schema": { "type": "number" }, "example": 106.71 }
        ],
        "responses": { "200": { "description": "Danh sách incident", "content": { "application/json": {} } } }
      }
    }
  }
}
