AWS Location Service Documentation

Pilih operation di sidebar kiri untuk lihat detail endpoint, request body, response shape, dan perbandingan v0 ↔ v2.

Default provider di ap-southeast-1 = GrabMaps. Dokumentasi ini fokus untuk integrasi API.

Region Caveats β€” ap-southeast-1 (GrabMaps)
  • Map styles: hanya Standard & Monochrome (Hybrid/Satellite ditolak)
  • Live Traffic parameter: ditolak. DepartureTime tetap honored via pola traffic historis per jam
  • Avoid options yang valid: TollRoads, Ferries, ControlledAccessHighways (DirtRoads/Tunnels/UTurns ditolak)
  • Waypoints: PassThrough tidak didukung β€” omit field-nya
  • Routes return Tolls dan MajorRoadLabels β€” tapi AWS jarang populate field ini di SEA
  • Suggest tidak return Position by default β€” tambah AdditionalFeatures: ['Core']
  • GetPlace: Contacts, OpeningHours, Brand, FoodTypes jarang populated di SEA
  • Places AdditionalFeatures: hanya TimeZone yang dilayani β€” Contact, Access, Phonemes membalas 400
  • Ditolak 400 di semua operasi Places: PoliticalView, NextToken, MaxQueryRefinements. QueryId tidak bisa didapat karena Suggest hanya mengembalikan item bertipe Place

Operation

⏳ Coming Soon

Operation ini belum tersedia di API key kamu untuk region ap-southeast-1.

Dokumentasi detail akan ditambahkan setelah AWS rilis action ini di region kamu. Sementara, cek alternatif yang sudah available di sidebar (dot hijau).

CalculateRoutes

Hitung rute dari Origin ke Destination, dengan opsi waypoints, mode kendaraan, hindari toll/ferry, dan turn-by-turn instructions.

POSThttps://routes.geo.{region}.amazonaws.com/v2/routes?key=...
Hasil dari AWS
Response β€” idle β€”
Tekan "Kirim ke AWS" di perakit request untuk melihat balasan aslinya.
Request Syntax
{
      "Origin": [ number, number ],
      "Destination": [ number, number ],
      "Waypoints": [ { "Position": [ number, number ], "StopDuration": number } ]   // StopDuration & PassThrough: 400 di region ini,
      "TravelMode": "Car" | "Scooter" | "Pedestrian",   // tier: Core
      "TravelStepType": "Default" | "TurnByTurn",
      "LegGeometryFormat": "Simple" | "FlexiblePolyline",
      "InstructionsMeasurementSystem": "Metric" | "Imperial",
      "Locale": "string",
      "Avoid": {
        "TollRoads": boolean,
        "Ferries": boolean,
        "ControlledAccessHighways": boolean
      },
      "DepartureTime": "string",
      "OptimizeRoutingFor": "FastestRoute" | "ShortestRoute",
      "MaxAlternatives": 0..5
    }

Hanya TravelMode yang memindahkan keranjang harga: Car dan Pedestrian masuk Core, Scooter masuk Advanced β€” tapi untuk pelanggan GrabMaps di region ini ikut dihitung Core. Pemicu Premium (tol dan Intermodal) tidak bisa dipanggil dari ap-southeast-1.

Request Parameters
Field Type Required Note
Origin [lng, lat] YES Starting point
Destination [lng, lat] YES End point
Waypoints array β€” Max 23 (excluding Origin & Destination)
TravelMode enum — Default: Car. v0→v2 mapping: Motorcycle→Scooter, Walking→Pedestrian
LegGeometryFormat enum β€” Simple = LineString array, FlexiblePolyline = encoded
Avoid.TollRoads boolean β€” Not supported for Pedestrian
DepartureTime ISO 8601 β€” Mutually exclusive with ArrivalTime
OptimizeRoutingFor enum β€” Default: FastestRoute
MaxAlternatives 0–6 β€” Request alternative routes. Response Routes[] = primary + alternatives. Actual count depends on geography (kadang AWS return lebih sedikit dari yang diminta).
TravelStepType enum β€” Set ke TurnByTurn untuk dapat full turn-by-turn instructions (VehicleLegDetails.TravelSteps[] dengan Type/SteeringDirection/CurrentRoad/NextRoad).
⚠️ Region caveats (ap-southeast-1): Avoid.DirtRoads, Avoid.Tunnels, Avoid.UTurns ditolak dengan FieldValidationFailed. Hanya TollRoads, Ferries, ControlledAccessHighways yang valid. Live Traffic parameter juga ditolak β€” DepartureTime akan honored lewat pola traffic historis per jam.
Response Syntax
{
      "PricingBucket": "string",
      "LegGeometryFormat": "string",
      "Notices": [...],
      "Routes": [
        {
          "Summary": { "Distance": number, "Duration": number },
          "Legs": [
            {
              "Distance": number,
              "Duration": number,
              "Geometry": { "LineString": [ [lng, lat], ... ] },
              "TravelMode": "string",
              "Type": "Vehicle" | "Pedestrian" | "Ferry",
              "VehicleLegDetails": {
                "TravelSteps": [ { "Distance": number, "Duration": number, "Instruction": "string" } ]
              }
            }
          ]
        }
      ]
    }
Response Fields
Field Type Note
Routes[0].Summary.Distance number Meters (not km like v0)
Routes[0].Summary.Duration number Seconds (previously DurationSeconds)
Routes[0].Legs[].Geometry.LineString array Array of [lng, lat] for MapLibre LineString
Routes[0].Legs[].Type enum Vehicle / Pedestrian / Ferry
Routes[0].Legs[].VehicleLegDetails.TravelSteps array Turn-by-turn instructions (when TravelStepType=TurnByTurn)
Common Errors
Status Trigger AWS Message
400 Tanpa Origin atau Destination "Origin/Destination is required"
400 Avoid.TollRoads dengan TravelMode: Pedestrian "TollRoads not supported for Pedestrian"
400 Waypoints > 23 "...less than or equal to 23"
400 Kirim DepartureTime + ArrivalTime bareng "Only one of DepartureTime/ArrivalTime allowed"
400 Origin/Destination tidak bisa di-reach (mis. tengah laut) "No route found"
POST/routes/v0/calculators/{Calc}/calculate/route?key=...
Request Body
{
  "DeparturePosition": [106.84, -6.20],
  "DestinationPosition": [106.85, -6.24],
  "WaypointPositions": [[106.846, -6.21]],
  "TravelMode": "Car",
  "DistanceUnit": "Kilometers",
  "IncludeLegGeometry": true,
  "AvoidTolls": true,
  "DepartNow": true
}
Response
{
  "Summary": { "Distance": 5.2, "DurationSeconds": 720 },
  "Legs": [{ "Distance": 5.2, "DurationSeconds": 720,
             "Geometry": { "LineString": [[106.84,-6.20], ...] } }]
}
Differences from v2:
  • DeparturePosition β†’ Origin, DestinationPosition β†’ Destination
  • WaypointPositions: [[lng,lat]] β†’ Waypoints: [{ Position: [lng,lat] }]
  • AvoidTolls: bool β†’ Avoid: { TollRoads: bool } (nested)
  • TravelMode: Motorcycle β†’ Scooter, Walking β†’ Pedestrian
  • Distance v0 dalam kilometer, v2 meter
  • DurationSeconds β†’ Duration
  • Response wrapper: v0 langsung Summary/Legs, v2 ada Routes[0] array

CalculateRouteMatrix

Hitung jarak & waktu untuk semua kombinasi origin Γ— destination β€” efisien untuk "find nearest" use case.

POSThttps://routes.geo.{region}.amazonaws.com/v2/route-matrix?key=...
Hasil dari AWS
Response β€” idle β€”
Tekan "Kirim ke AWS" di perakit request untuk melihat balasan aslinya.
Request Syntax
{
      "Origins": [ { "Position": [ number, number ] } ],
      "Destinations": [ { "Position": [ number, number ] } ],
      "TravelMode": "Car" | "Scooter" | "Pedestrian",   // tier: Core
      "RoutingBoundary": {
        "Unbounded": true,
        "Geometry": { "AutoCircle": { "Margin": number, "MaxRadius": number } }
      },
      "Avoid": {
        "TollRoads": boolean,
        "Ferries": boolean
      },
      "DepartureTime": "string",
      "OptimizeRoutingFor": "FastestRoute" | "ShortestRoute"
    }

Hanya TravelMode yang memindahkan keranjang harga: Car dan Pedestrian masuk Core, Scooter masuk Advanced β€” tapi untuk pelanggan GrabMaps di region ini ikut dihitung Core. Pemicu Premium (tol dan Intermodal) tidak bisa dipanggil dari ap-southeast-1.

Request Parameters
Field Type Required Note
Origins array YES Array of { Position: [lng,lat] }
Destinations array YES Array of { Position: [lng,lat] }
RoutingBoundary object YES WAJIB di v2! { Unbounded: true } untuk perilaku v0.
TravelMode enum β€” Default: Car
Avoid.TollRoads boolean β€” Not allowed for Pedestrian
Response Syntax
{
      "PricingBucket": "string",
      "RouteMatrix": [
        [
          { "Distance": number, "Duration": number, "Error": null }
        ]
      ],
      "ErrorCount": number
    }
Response Fields
Field Type Note
RouteMatrix[i][j].Distance number Meter (v0: km)
RouteMatrix[i][j].Duration number Detik (v0: DurationSeconds)
RouteMatrix[i][j].Error object|null Per-cell error (e.g. unreachable). null if OK.
Common Errors
Status Trigger AWS Message
400 Tanpa RoutingBoundary "RoutingBoundary is required"
400 Origins Γ— Destinations > 700 "Too many cells: max 700"
400 Position kosong di salah satu Origins/Destinations "Position is required"
POST/routes/v0/calculators/{Calc}/calculate/route-matrix?key=...
Request Body
{
  "DeparturePositions": [[106.84, -6.20]],
  "DestinationPositions": [[106.85,-6.24], [106.86,-6.25]],
  "TravelMode": "Car",
  "DistanceUnit": "Kilometers"
}
Response (km, DurationSeconds)
{
  "RouteMatrix": [[
    { "Distance": 1.2, "DurationSeconds": 240 },
    { "Distance": 2.5, "DurationSeconds": 480 }
  ]]
}
Differences from v2:
  • DeparturePositions: [[lng,lat]] β†’ Origins: [{ Position: [lng,lat] }]
  • DestinationPositions: [[lng,lat]] β†’ Destinations: [{ Position: [lng,lat] }]
  • v2 wajib RoutingBoundary (v0 tidak)
  • Distance: v0 km β†’ v2 meter
  • DurationSeconds β†’ Duration

CalculateIsolines v2 only

Polygon area "reachable within X minutes" atau "within Y km" dari satu titik. Cocok untuk visualisasi service coverage.

⏳ Coming Soon Not available in region ap-southeast-1. Action not listed in AWS Console permissions. Wait for AWS rollout or use the workaround below.
POST/v2/isolines?key=...

Request body

{
  "Origin": [106.84, -6.20],
  "TravelMode": "Car",
  "Thresholds": {
    "Time": [300, 600, 900]
  },
  "OptimizeIsolineFor": "FastestRoute"
}

Bisa juga pakai Thresholds.Distance (meter) atau kedua-duanya.

Response

{
  "Isolines": [{
    "TimeThreshold": 300,
    "Geometries": [{
      "Polygon": [[ [106.83,-6.19], ... ]]
    }]
  }]
}
πŸ’‘ Use case: visualize "stops reachable within 10 minutes on foot" with polygon overlay on MapLibre.

OptimizeWaypoints v2 only

TSP solver β€” kasih AWS list of waypoints, dia kembalikan urutan optimal (ngirit jarak/waktu).

⏳ Coming Soon Not available in region ap-southeast-1. For this feature, implement nearest-neighbor TSP yourself in JS or use a library.
POST/v2/optimize-waypoints?key=...

Request body

{
  "Origin": [106.84, -6.20],
  "Destination": [106.92, -6.30],
  "Waypoints": [
    { "Id": "stop1", "Position": [106.85,-6.21] },
    { "Id": "stop2", "Position": [106.90,-6.22] },
    { "Id": "stop3", "Position": [106.87,-6.25] }
  ],
  "TravelMode": "Car",
  "OptimizeSequencingFor": "FastestRoute"
}

Response

{
  "OptimizedWaypoints": [
    { "Id": "stop1", "Position": [106.85,-6.21] },
    { "Id": "stop3", "Position": [106.87,-6.25] },
    { "Id": "stop2", "Position": [106.90,-6.22] }
  ],
  "Distance": 12500,
  "Duration": 1850
}
βœ… Sebelumnya kamu harus implement TSP / nearest-neighbor sendiri di JS. Sekarang AWS yang hitungkan.

SnapToRoads v2 only

Snap GPS trace yang noisy ke jalan terdekat. Berguna untuk clean trip log GPS dari kendaraan.

⏳ Coming Soon Not available in region ap-southeast-1. Not yet rolled out for GrabMaps provider.
POST/v2/snap-to-roads?key=...

Request body

{
  "TracePoints": [
    { "Position": [106.840, -6.200] },
    { "Position": [106.842, -6.201] },
    { "Position": [106.845, -6.203] }
  ],
  "TravelMode": "Car",
  "SnappedGeometryFormat": "Simple"
}

Response

{
  "SnappedGeometry": {
    "LineString": [[106.840,-6.200], [106.843,-6.201], ...]
  },
  "SnappedTracePoints": [
    { "OriginalPosition": [106.840,-6.200], "SnappedPosition": [106.840,-6.200] }
  ]
}
πŸ’‘ Pair with ride-hailing trip recording to get clean trip lines (without GPS-noise zigzags).

GetStyleDescriptor

Return MapLibre style spec JSON. URL ini langsung ditaroh di property style waktu inisialisasi MapLibre map.

GEThttps://maps.geo.{region}.amazonaws.com/v2/styles/{Style}/descriptor?key=...
Query Parameters
Param Values Note
{Style}PATH enum Standard | Monochrome | Hybrid | Satellite In ap-southeast-1: only Standard & Monochrome (GrabMaps provider)
keyREQ string API key
color-scheme enum Light | Dark Only for Standard / Monochrome
political-view string ISO-3 IDN, MYS, ARG, MAR, etc.
Field Rules
Style + Color compatibility
Standard + Light/Dark βœ“
Monochrome + Light/Dark βœ“
Hybrid/Satellite + color-scheme ❌
Raster styles (Hybrid/Satellite) don't accept color-scheme β€” sending it returns error 400.
Common Errors
Status Trigger AWS Message
400 Style not available in region (e.g. Satellite in ap-southeast-1) "Satellite is not a supported map style"
400 color-scheme used on Hybrid/Satellite "color-scheme not applicable"
403 API Key lacks geo-maps:GetStyleDescriptor "explicit deny"
Response (JSON)
{
  "version": 8,
  "name": "Standard",
  "sources": {
    "tiles": { "type": "vector", "tiles": [ "https://maps.geo.../v2/tiles/Standard/Default/Default/{z}/{x}/{y}?key=..." ] }
  },
  "sprite": "https://maps.geo.../v2/sprites/Standard/Default/Default",
  "glyphs": "https://maps.geo.../v2/glyphs/Standard/{fontstack}/{range}?key=...",
  "layers": [ ... ]
}

Style descriptor is a complete MapLibre recipe β€” it contains URLs for GetTile / GetGlyphs / GetSprites. MapLibre auto-fetches all three.

Try it Live
πŸ’‘ Pick style + color + political-view β†’ the MapLibre map below auto re-renders with the new style descriptor.
 Presets
URL
GET/maps/v0/maps/{MapName}/style-descriptor?key=...
Differences from v2:
  • Pakai {MapName} custom resource (harus dibuat dulu di Console)
  • Tidak ada color-scheme / political-view param
  • Provider lock per resource β€” gak bisa switch style runtime

GetTile

Vector / raster tile per koordinat z/x/y. URL pattern ini ada di field tiles dalam style descriptor β€” biasanya gak perlu di-call manual.

GEThttps://maps.geo.{region}.amazonaws.com/v2/tiles/{Tileset}/{z}/{x}/{y}?key=...
Request Syntax
GET https://maps.geo.{region}.amazonaws.com/v2/tiles/vector.basemap/{z}/{x}/{y}
      ?key=<API_KEY>

Maps cuma punya satu harga per 1.000 tile β€” tidak ada tier di operasi ini. Nama tileset diambil dari field tiles di style descriptor.

Path / Query Parameters
Param Type Note
{Tileset} path vector.basemap β€” nama tileset, diambil dari field tiles di style descriptor. Gaya dan color scheme ditentukan descriptor-nya, bukan URL tile ini.
{z}/{x}/{y} path int Tile coordinate (z 0-22, x/y per zoom level)
key query API key
Common Errors
Status Trigger Note
400 z/x/y out of valid range E.g. y > 2^z - 1
404 Tile not available in this area E.g. coordinate outside provider coverage
403 API Key lacks geo-maps:GetTile Permission missing
Response Content-Type
Style Content-Type Format
Standard / Monochrome application/x-protobuf Vector tile (PBF) β€” rendered by MapLibre client-side
Hybrid / Satellite image/png atau image/jpeg Raster tile, rendered as-is
Try it Live
πŸ’‘ Use the z/x/y picker to view a specific tile. Vector tile (PBF) cannot be previewed directly β€” use MapLibre to render it.
z/x/y
URL

⬆️ Test mengambil tile dan melaporkan status, tipe, serta ukurannya di sini. Open membuka URL-nya langsung β€” tile vektor akan terunduh sebagai berkas biner, dan Chrome memblokirnya kalau halaman ini masih diakses lewat HTTP.

GET/maps/v0/maps/{MapName}/tiles/{z}/{x}/{y}?key=...
Differences from v2:
  • Path lebih sederhana: {MapName}/tiles/{z}/{x}/{y}
  • Tidak ada Style/ColorScheme/Variant β€” provider locked di resource

GetGlyphs

Font glyphs (PBF) untuk text rendering di vector tiles. Auto-fetched oleh MapLibre, gak perlu di-call manual.

GEThttps://maps.geo.{region}.amazonaws.com/v2/glyphs/{Style}/{fontstack}/{range}?key=...
Path Parameters
Param Type Note
{Style} path Standard | Monochrome
{fontstack} path Nama font (mis. Noto Sans Regular) β€” URL-encoded
{range} path Unicode range, 256 chars per chunk: 0-255, 256-511, dst.
Response Content-Type

application/x-protobuf β€” binary PBF berisi font glyphs. Di-decode sama MapLibre untuk render label di map.

Common Errors
Status Trigger Note
404 Fontstack not available See available fonts in the style descriptor
400 Invalid range Max range usually up to 65279 (basic Unicode)
403 Permission missing geo-maps:GetGlyphs gak di-grant
Try it Live
πŸ’‘ Glyphs PBF cannot be previewed directly. Shown here: URL builder + open button to download the file.
Style Font Range
URL
GET/maps/v0/maps/{MapName}/glyphs/{fontstack}/{range}?key=...
Differences from v2:
  • Path: {MapName}/glyphs/{fontstack}/{range} (tanpa Style)
  • Font set tergantung MapName resource

GetSprites

Sprite sheet (PNG + JSON) untuk icon point-of-interest di map. Auto-fetched oleh MapLibre.

GEThttps://maps.geo.{region}.amazonaws.com/v2/sprites/{Style}/{ColorScheme}/{Variant}/{file}?key=...
Path Parameters
Param Type Note
{Style} path Standard | Monochrome
{ColorScheme} path Light | Dark | Default
{Variant} path Default
{file} path sprites.json | sprites.png | sprites@2x.json | sprites@2x.png
Response Content-Type
File Content-Type Note
sprites.json application/json Manifest: coordinates & size of each icon in the sheet
sprites.png image/png Sheet image β€” all icons in one PNG
sprites@2x.png image/png @2x version for retina display
Try it Live
πŸ’‘ PNG sprites can be previewed directly. JSON manifest can be fetched to inspect structure.
Style Color File
URL
Sprite preview
GET/maps/v0/maps/{MapName}/sprites?key=...
Differences from v2:
  • Path: {MapName}/sprites (tanpa Style/Color/Variant/file split)
  • v0 punya endpoint terpisah untuk JSON vs PNG (mis. /sprites?json=true)
  • Sprite set lock per provider

GetStaticMap v2 only

Render map jadi gambar PNG/JPEG single. Cocok untuk thumbnail, preview di card, email, atau social sharing.

⏳ Coming Soon Not available in region ap-southeast-1. Maps Actions in Console only has GetTile. Workaround: screenshot from MapLibre canvas.
GET/v2/static-map?key=...&...

Query parameters

Param Type Note
CenterREQ lng,lat Map center
ZoomREQ number 0-22
WidthREQ number Pixel
HeightREQ number Pixel
Style β€” Standard | Monochrome | Hybrid | Satellite
FileFormat β€” png | jpeg
Pins array Optional marker overlay

Example

GET/v2/static-map?key=...&Center=106.84,-6.20&Zoom=14&Width=600&Height=400&Style=Standard

Hasil: gambar PNG 600Γ—400 pusat di Sudirman zoom 14.

SearchText

Pencarian Place (POI / alamat / area) berbasis free-form text. Cocok untuk search bar dengan tombol "Search". Mendukung bias position, filter geografis (BoundingBox/Circle/Country), dan filter kategori.

POSThttps://places.geo.{region}.amazonaws.com/v2/search-text?key=...
Hasil dari AWS
Response β€” idle β€”
Tekan "Kirim ke AWS" di perakit request untuk melihat balasan aslinya.
Request Syntax
{
  "QueryText": "string",
  "MaxResults": number,
  "BiasPosition": [ number, number ],
  "Filter": {
    "BoundingBox": [ number, number, number, number ],
    "Circle": {
      "Center": [ number, number ],
      "Radius": number
    },
    "IncludeCountries": [ "string" ]
  },
  "AdditionalFeatures": [ "TimeZone" ],      // tier: Advanced
  "Language": "string",
  "IntendedUse": "SingleUse" | "Storage"     // tier: Stored
}

Baris yang diberi pil tier menentukan keranjang harga. Tanpa satu pun penanda, panggilan masuk Core; Stored hanya kalau IntendedUse diisi Storage.

Request Parameters
Field Type Required Note
QueryText string YES Free-form keyword (1-200 char). *Required: one of QueryText or QueryId.
MaxResults number β€” 1–100, default 20
BiasPosition [lng, lat] YES* Bias ranking + reference for the Distance field. Exactly 1 of BiasPosition / Filter.BoundingBox / Filter.Circle.
πŸ“Œ Use this if you need Distance β€” Filter.Circle/BoundingBox don't trigger Distance in ap-southeast-1.
Filter.BoundingBox [w, s, e, n] β€” Limit results to a box (west, south, east, north)
Filter.Circle object β€” Center: [lng,lat], Radius: meter (max 50000)
Filter.IncludeCountries array<string> β€” ISO-3 country codes, e.g. ["IDN"]
AdditionalFeatures array<string> β€” Advanced Contact | TimeZone | Phonemes | Access. Di ap-southeast-1 hanya TimeZone yang dilayani.
Language string β€” BCP 47 (e.g. id, en)
IntendedUse string β€” Stored SingleUse (default) | Storage
Contoh bentuk balasan β€” tekan "Kirim ke AWS" untuk balasan asli.
{
      "ResultItems": [
        {
          "PlaceId": "AQAAAC0A2MtBKefVps2gjOatU5vuegwizzHZ2R53...",
          "PlaceType": "PointOfInterest",
          "Title": "Silang Monas Jakarta Pusat",
          "Address": {
            "Label": "Silang Monas, Gambir, Daerah Khusus Ibukota Jakarta, 10110",
            "Country": { "Code2": "ID", "Code3": "IDN", "Name": "Indonesia" },
            "Locality": "DKI Jakarta",
            "District": "Gambir",
            "SubDistrict": "Gambir",
            "PostalCode": "10110",
            "Street": "Jalan Medan Merdeka Barat",
            "AddressNumber": "12"
          },
          "Position": [ 106.826, -6.175 ],
          "MapView": [ 106.824, -6.177, 106.828, -6.173 ],
          "Distance": 640,
          "Categories": [
            { "Id": "monument", "Name": "Monument", "LocalizedName": "monumen", "Primary": true }
          ],
          "TimeZone": { "Name": "Asia/Jakarta", "Offset": "UTC+07:00", "OffsetSeconds": 25200 }
        }
      ]
    }

Field Type Note
ResultItems[].PlaceId string Unique AWS ID β€” use with GetPlace to fetch full detail
ResultItems[].PlaceType string PointOfInterest | Address | Street | District | Region | etc.
ResultItems[].Title string Main display name
ResultItems[].Position [lng, lat] Center coordinate of the place
ResultItems[].Distance number Meters from reference point.
⚠️ Empirical in ap-southeast-1: this field only appears when the request uses BiasPosition. When using Filter.Circle or Filter.BoundingBox, the Distance field is absent from the response.
Workaround: compute Haversine in JS from Position to the origin.
ResultItems[].Address object Structured address (label + components)
ResultItems[].MapView [w,s,e,n] Bounding box for fitting the map
ResultItems[].Categories array Kategori AWS (mis. transit_station_bus)
Status Trigger AWS Message
400 2+ of BiasPosition / Filter.BoundingBox / Filter.Circle sent together "Exactly one of the following fields must be set: BiasPosition, Filter.BoundingBox, Filter.Circle."
400 No QueryText and no QueryId "Either QueryText or QueryId is required."
400 MaxResults > 20 "Member must have value less than or equal to 20"
400 Filter.Circle.Radius > 50000 "Member must have value less than or equal to 50000"
400 Wrong coordinate format (e.g. [lat, lng] instead of [lng, lat]) Weird / empty result β€” AWS doesn't validate ranges, coords are accepted as-is
400 Filter.IncludeCountries not ISO-3 (e.g. "Indonesia" or "ID") "Validation failed: country code must be 3 letters"
403 API Key lacks action geo-places:SearchText "User is not authorized to access this resource with an explicit deny"
403 API Key wrong or missing ?key= "The security token included in the request is invalid"
429 Rate limit exceeded (default 50 TPS) "Rate exceeded" β€” implement retry with backoff
POSThttps://places.geo.{region}.amazonaws.com/places/v0/indexes/{IndexName}/search/text?key=...
Request Body
{
  "Text": "halte TJ",
  "BiasPosition": [106.84, -6.20],
  "MaxResults": 10,
  "FilterCountries": ["IDN"]
}
Response Body
{
  "Summary": { "Text": "halte TJ", "MaxResults": 10, "ResultBBox": [...] },
  "Results": [
    {
      "Place": {
        "Label": "Halte TJ Halimun, Jakarta",
        "Geometry": { "Point": [106.85, -6.24] },
        "Country": "IDN",
        "AddressNumber": "5"
      },
      "Distance": 850.42
    }
  ]
}
Differences from v2:
  • Field Text β†’ QueryText
  • FilterCountries β†’ Filter.IncludeCountries
  • Response: Results[].Place.Geometry.Point β†’ ResultItems[].Position
  • MaxResults max 10 (v2: 20)
  • Must create PlaceIndex resource first in AWS Console

Suggest

Autocomplete ketik-langsung untuk dropdown. Di ap-southeast-1 yang kembali selalu Place β€” saran perbaikan kueri butuh MaxQueryRefinements yang ditolak di sini.

POSThttps://places.geo.{region}.amazonaws.com/v2/suggest?key=...
Hasil dari AWS
Response β€” idle β€”
Tekan "Kirim ke AWS" di perakit request untuk melihat balasan aslinya.
Request Syntax
{
      "QueryText": "string",
      "MaxResults": number,
      "BiasPosition": [ number, number ],
      "Filter": {
        "BoundingBox": [ number, number, number, number ],
        "Circle": { "Center": [ number, number ], "Radius": number },
        "IncludeCountries": [ "string" ]
      },
      "AdditionalFeatures": [ "Core" | "TimeZone" ],   // tier: Core/Advanced
      "Language": "string"
    }

Baris yang diberi pil tier menentukan keranjang harga. Tanpa AdditionalFeatures, panggilan masuk Label β€” keranjang termurah. Suggest tidak menerima IntendedUse: "Storage", jadi tidak ada tier Stored di sini.

Request Parameters
Field Type Required Note
QueryText string YES 1–200 char. Partial keyword OK (autocomplete).
MaxResults number β€” 1–100, bawaan 5
BiasPosition [lng, lat] β€” Exactly 1 dari Bias / Filter.Circle / Filter.BoundingBox.
Filter.Circle object β€” Center: [lng,lat], Radius: meter (max 50000)
Filter.BoundingBox [w,s,e,n] β€” west, south, east, north
Filter.IncludeCountries array β€” ISO-3 codes
Language string β€” BCP 47 (e.g. id)
AdditionalFeatures array β€” CoreAdvanced Valid: Core, TimeZone, Phonemes. Tip: tambah "Core" untuk unlock field Position di response β€” tanpa ini Suggest gak return koordinat (jadi distance ke marker user gak bisa dihitung client-side).
πŸ’‘ Penting untuk autocomplete dengan distance: response Suggest tidak include Position by default. Kirim "AdditionalFeatures": ["Core"] untuk dapat lat/lng tiap suggestion β€” supaya bisa compute distance dari current marker/map center langsung di client.
Response Syntax
{
      "ResultItems": [
        {
          "Title": "string",
          "SuggestResultItemType": "Place",
          "Highlights": {                              // hanya dengan AdditionalFeatures: ["Core"]
            "Title": [ { "StartIndex": number, "EndIndex": number, "Value": "string" } ],
            "Address": { "Label": [ { "StartIndex": number, "EndIndex": number, "Value": "string" } ] }
          },
          "Place": {
            "PlaceId": "string",
            "PlaceType": "string",
            "Address": { "Label": "string", "Country": { ... }, "Locality": "string", "Street": "string" },
            "Position": [ number, number ],               // AdditionalFeatures: ["Core"]
            "Distance": number,                           // AdditionalFeatures: ["Core"]
            "MapView": [ number, number, number, number ],
            "Categories": [ { "Id": "string", "Name": "string", "LocalizedName": "string", "Primary": boolean } ],
            "TimeZone": { "Name": "string", "Offset": "string", "OffsetSeconds": number }
          }
        }
      ]
    }

ResultItems satu-satunya kunci di badan respons; PricingBucket dikirim sebagai header x-amz-geo-pricing-bucket. SuggestResultItemType selalu Place β€” item Query butuh MaxQueryRefinements yang ditolak 400 di ap-southeast-1.

Response Fields
Field Type Note
SuggestResultItemType enum Place = actual hit, Query = refinement keyword
Place.Position [lng,lat] Only for SuggestResultItemType=Place
Place.Distance number Meters (only when using BiasPosition)
Highlights.Title array Range index for highlighting matched keywords
Query.QueryId string Pass to SearchText as QueryId for full search
Common Errors
Status Trigger AWS Message
400 2+ spatial filter "Exactly one of..."
400 Empty QueryText "QueryText: Member must have length greater than or equal to 1"
400 MaxResults > 100 "...less than or equal to 10"
403 Action geo-places:Suggest tidak di-grant "explicit deny"
POST/places/v0/indexes/{Idx}/search/suggestions?key=...
Request Body
{
  "Text": "halte tj",
  "BiasPosition": [106.84, -6.20],
  "MaxResults": 5,
  "FilterCountries": ["IDN"]
}
Response
{
  "Summary": { "Text": "halte tj" },
  "Results": [
    { "Text": "Halte Transjakarta Halimun", "PlaceId": "AQABA..." }
  ]
}
Differences from v2:
  • Text β†’ QueryText
  • FilterCountries β†’ Filter.IncludeCountries
  • Results[].Text β†’ ResultItems[].Title
  • v0 tidak return Position di Suggest β€” harus call GetPlace

ReverseGeocode

Koordinat β†’ alamat terdekat.

POSThttps://places.geo.{region}.amazonaws.com/v2/reverse-geocode?key=...
Hasil dari AWS
Response β€” idle β€”
Tekan "Kirim ke AWS" di perakit request untuk melihat balasan aslinya.
Request Syntax
{
      "QueryPosition": [ number, number ],
      "QueryRadius": number,
      "MaxResults": number,
      "Filter": {
        "IncludeCountries": [ "string" ]
      },
      "AdditionalFeatures": [ "TimeZone" ],      // tier: Advanced
      "Language": "string",
      "IntendedUse": "SingleUse" | "Storage"     // tier: Stored
    }

Baris yang diberi pil tier menentukan keranjang harga. Tanpa satu pun penanda, panggilan masuk Core; Stored hanya kalau IntendedUse diisi Storage.

Request Parameters
Field Type Required Note
QueryPosition [lng, lat] YES Coordinate point to reverse-geocode
QueryRadius number β€” Radius pencarian dalam meter, 1–100000. Nilai 0 ditolak 400
MaxResults number β€” 1–100, bawaan 1
AdditionalFeatures array β€” Advanced TimeZone | Intersections. Di ap-southeast-1 hanya TimeZone yang dilayani.
Language string β€” BCP 47
IntendedUse string β€” Stored SingleUse (default) | Storage
Filter.IncludeCountries array<string> β€” Kode negara ISO-3, mis. ["IDN"]
Response Syntax
{
      "ResultItems": [
        {
          "PlaceId": "string",
          "PlaceType": "string",
          "Title": "string",
          "Address": {
            "Label": "string",
            "Country": { "Code2": "string", "Name": "string" },
            "Region": { "Code": "string", "Name": "string" },
            "PostalCode": "string"
          },
          "Position": [ number, number ],
          "Distance": number,
          "MapView": [ number, number, number, number ]
        }
      ]
    }

ResultItems satu-satunya kunci di badan respons β€” PricingBucket dikirim sebagai header x-amz-geo-pricing-bucket. Tiap item selalu membawa Position, Distance, MapView, dan Categories; TimeZone hanya kalau diminta.

Response Fields
Field Type Note
ResultItems[].Title string Short location name
ResultItems[].Address.Label string Full formatted address
ResultItems[].Distance number Meters from QueryPosition
ResultItems[].PlaceType string Locality, District, Street, PointAddress, dst.
Common Errors
Status Trigger AWS Message
400 Tanpa QueryPosition "QueryPosition is required"
400 Format [lat, lng] (terbalik) Hasil aneh β€” AWS treat sebagai [lng, lat]
400 MaxResults > 100 "...less than or equal to 4"
POST/places/v0/indexes/{Idx}/search/position?key=...
Request Body
{
  "Position": [106.84, -6.20],
  "MaxResults": 1
}
Differences from v2:
  • Position β†’ QueryPosition
  • Tidak ada Filter.IncludePlaceTypes di v0
  • Wajib bikin PlaceIndex resource dulu

GetPlace

Detail lengkap Place by PlaceId (dari hasil Search/Suggest sebelumnya).

GEThttps://places.geo.{region}.amazonaws.com/v2/place/{PlaceId}?key=...&...
πŸ’‘ Dapat PlaceId dulu dari Try it Live SearchText/Suggest, copy hasil ResultItems[0].PlaceId, paste ke sini.
Hasil dari AWS
Response β€” idle β€”
Masukkan PlaceId lalu klik Send Request.
Request Syntax
GET https://places.geo.{region}.amazonaws.com/v2/place/{PlaceId}
          ?key=<API_KEY>
          &additional-features=TimeZone     # tier: Advanced
          &language=id
          &intended-use=Storage             # tier: Stored

Baris yang diberi pil tier menentukan keranjang harga. Tanpa keduanya, panggilan masuk Core dan intended-use dianggap SingleUse. Di ap-southeast-1 intended-use=Storage ditolak 400.

Query Parameters
Param Type Required Note
{PlaceId} path YES Path segment (URL-encoded). From SearchText/Suggest.
key query YES API key
additional-features query β€” Advanced Comma-separated: TimeZone, Contact, Access, Phonemes, SecondaryAddresses. Di ap-southeast-1 hanya TimeZone yang dilayani.
language query β€” BCP 47 (e.g. id, en)

Baris yang diberi pil tier menentukan keranjang harga. Tanpa satu pun penanda, panggilan masuk Core; Stored hanya kalau IntendedUse diisi Storage.

Response Syntax
{
      "PlaceId": "string",
      "PlaceType": "string",
      "Title": "string",
      "Address": {
        "Label": "string",
        "Country": { "Code2": "string", "Name": "string" },
        "Region": { "Code": "string", "Name": "string" },
        "Locality": "string",
        "PostalCode": "string"
      },
      "Position": [ number, number ],
      "MapView": [ number, number, number, number ],
      "Categories": [ { "Id": "string", "Name": "string", "Primary": boolean } ],
      "Contacts": {
        "Phones": [ { "Value": "string" } ],
        "Websites": [ { "Value": "string" } ]
      },
      "OpeningHours": [
        { "Display": [ "string" ], "OpenNow": boolean }
      ],
      "TimeZone": { "Name": "string", "Offset": "string", "OffsetSeconds": number }
    }

Balasannya objek tunggal, bukan ResultItems. Tidak ada Distance β€” GetPlace tidak punya titik acuan. PricingBucket dikirim sebagai header x-amz-geo-pricing-bucket.

Common Errors
Status Trigger AWS Message
400 PlaceId tidak sah, dipotong, atau salah ketik "'PlaceId' must be a valid ID."
400 additional-features berisi value yang gak disupport region "Unsupported AdditionalFeatures..."
403 API Key tidak punya geo-places:GetPlace "explicit deny"
GET/places/v0/indexes/{Idx}/places/{PlaceId}?key=...
Differences from v2:
  • Path beda: /places/v0/indexes/{Idx}/places/{PlaceId}
  • Tidak ada additional-features param di v0
  • Response shape lebih simple, tanpa OpeningHours, Contacts, TimeZone

Autocomplete v2 only

Type-ahead khusus untuk alamat (street, address number, postal code) β€” bukan untuk POI.

POST/v2/autocomplete?key=...

Request body

{
  "QueryText": "Jl. Sudirman",
  "BiasPosition": [106.84, -6.20],
  "Filter": {
    "IncludeCountries": ["IDN"],
    "IncludePlaceTypes": ["Street", "PointAddress"]
  },
  "MaxResults": 5,
  "Language": "id"
}

Response (does NOT return Position)

{
  "ResultItems": [{
    "Title": "Jl. Jenderal Sudirman, Jakarta",
    "PlaceId": "AQAB...",
    "Address": { "Label": "..." },
    "Distance": 1250,
    "Highlights": { ... }
  }]
}
⚠️ Does not return Position β€” must call GetPlace per item if you need coordinates. For finding POIs, Suggest is more efficient (returns Position directly).
⏳ Coming Soon Not available in region ap-southeast-1 at the moment. Check AWS Console for available actions.

IncludePlaceTypes valid values

Locality | PostalCode | Intersection | Street | PointAddress | InterpolatedAddress

PointOfInterest is not valid in Autocomplete β€” use SearchText / SearchNearby.

Geocode v2 only

Alamat terstruktur (street, city, postal) β†’ koordinat. Lebih akurat dari SearchText untuk address lookup karena input-nya sudah parsed.

⏳ Coming Soon Not available in region ap-southeast-1. Workaround: use SearchText with structured QueryText.
POST/v2/geocode?key=...

Request body

{
  "QueryComponents": {
    "Country": "IDN",
    "Region": "Jakarta",
    "Locality": "Jakarta Selatan",
    "Street": "Jl. Sudirman",
    "AddressNumber": "1",
    "PostalCode": "10220"
  },
  "MaxResults": 1
}

Response

{
  "ResultItems": [{
    "Title": "Jl. Sudirman 1, Jakarta",
    "Position": [106.823, -6.224],
    "Address": { ... },
    "MatchScores": { "Overall": 0.95 }
  }]
}
πŸ’‘ Use this when you already have field-by-field address (e.g. from a form input). For free-text search, use SearchText.

SearchNearby v2 only

Find POI dalam radius dari satu titik, opsional filter by category. Tidak butuh QueryText β€” cuma "tunjukin yang dekat tipe X".

⏳ Coming Soon Not available in region ap-southeast-1. Workaround: use SearchText with Filter.Circle + category keyword in QueryText.
POST/v2/search-nearby?key=...

Request body

{
  "QueryPosition": [106.84, -6.20],
  "QueryRadius": 1000,
  "Filter": {
    "IncludeCategories": ["transit_station_bus"]
  },
  "MaxResults": 20,
  "Language": "id"
}

Response

{
  "ResultItems": [{
    "Title": "Halte Transjakarta Halimun",
    "PlaceId": "AQAB...",
    "Position": [106.85, -6.24],
    "Distance": 850,
    "Categories": [{ "Id": "transit_station_bus", "Primary": true }]
  }]
}
βœ… Untuk use case "halte terdekat" ini paling direct: 1 API call, sorted by distance, gak perlu QueryText. Prasyaratnya kamu tau ID kategori (mis. transit_station_bus).

Notes

  • Max QueryRadius = 50,000 m (50 km)
  • Max MaxResults = 20

Overview v0 vs v2

Dua generation API yang masih jalan paralel. v2 = standalone mode (recommended), v0 = legacy resource-based.

Aspek v0 Legacy v2 Standalone
Setup AWS Console Must create Map / PlaceIndex / RouteCalculator first Not needed β€” works immediately
Hostname maps.geo.{region}.amazonaws.com (shared) Per service: maps.geo, places.geo, routes.geo
Path version /{service}/v0/... /v2/...
Provider Lock per resource Auto-picked per region
Status ⚠️ Maintenance only βœ… Active development
Rekomendasi: Project baru pakai v2. Project existing tetap aman di v0 sampai AWS announce deprecation.

Authentication

Dua-duanya support API Key (recommended frontend) atau AWS SigV4 (backend).

API Key in URL

?key=v1.public.eyJq...

Resource ARN (per service)

Service v0 Legacy v2 Recommended
Maps arn:aws:geo:...:map/{Name} arn:aws:geo-maps:...::provider/default
Places arn:aws:geo:...:place-index/{Name} arn:aws:geo-places:...::provider/default
Routes arn:aws:geo:...:route-calculator/{Name} arn:aws:geo-routes:...::provider/default
⚠️ Saat bikin API Key di AWS Console, centang actions per service yang dibutuhkan. Action yang gak dicentang akan return 403 Forbidden (explicit deny).

Quotas & Limits

Limit per request untuk API Location v2.

Operation Param Limit
SearchText MaxResults 20
Suggest MaxResults 10
ReverseGeocode MaxResults 4
SearchNearby MaxResults 20
All Search Filter.Circle.Radius 50,000 m
CalculateRoutes Waypoints 23
CalculateRouteMatrix Origins Γ— Destinations 700 cells
Rate limit (default) β€” 50 TPS / account (Places)

Lengkap: Service Quotas

Migration v0 β†’ v2

Checklist 3-step untuk pindahin code dari v0 (resource-based) ke v2 (standalone).

1. Maps

  • Hapus dependency ke AWS_MAP_NAME
  • Ganti URL style ke /v2/styles/Standard/descriptor
  • Tambah API Key actions: geo-maps:*

2. Places

  • Hapus AWS_MAP_PLACE (PlaceIndex)
  • Endpoint: /places/v0/indexes/.../search/text β†’ /v2/search-text
  • Body: Text β†’ QueryText, FilterCountries β†’ Filter.IncludeCountries
  • Response: Results β†’ ResultItems, Place.Geometry.Point β†’ Position

3. Routes

  • Hapus AWS_MAP_ROUTE (RouteCalculator)
  • Endpoint ke /v2/routes & /v2/route-matrix
  • Body: DeparturePosition β†’ Origin, WaypointPositions β†’ Waypoints: [{Position}]
  • TravelMode: Motorcycle/Walking β†’ Scooter/Pedestrian
  • Distance v0 (km) β†’ v2 (meter), DurationSeconds β†’ Duration
  • Matrix: tambah RoutingBoundary: {Unbounded: true}
πŸ’‘ Test on a separate endpoint first (e.g. /transjakarta-test) before migrating production code.