AWS Location Service Reference
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.
- Map styles: hanya
Standard&Monochrome(Hybrid/Satellite ditolak) - Live
Trafficparameter: ditolak.DepartureTimetetap honored via pola traffic historis per jam - Avoid options yang valid:
TollRoads,Ferries,ControlledAccessHighways(DirtRoads/Tunnels/UTurns ditolak) - Waypoints:
PassThroughtidak didukung — omit field-nya - Routes return
TollsdanMajorRoadLabels— tapi AWS jarang populate field ini di SEA - Suggest tidak return
Positionby default — tambahAdditionalFeatures: ['Core'] - GetPlace:
Contacts,OpeningHours,Brand,FoodTypesjarang populated di SEA
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.
{
"Origin": [ number, number ],
"Destination": [ number, number ],
"Waypoints": [ { "Position": [ number, number ], "StopDuration": number } ],
"TravelMode": "Car" | "Scooter" | "Pedestrian" | "Truck",
"TravelStepType": "Default" | "TurnByTurn",
"LegGeometryFormat": "Simple" | "FlexiblePolyline",
"InstructionsMeasurementSystem": "Metric" | "Imperial",
"Locale": "string",
"Avoid": {
"TollRoads": boolean,
"Ferries": boolean,
"ControlledAccessHighways": boolean,
"DirtRoads": boolean,
"TruckRoadTypes": [ "string" ],
"Areas": [ { "Geometry": { "Polygon": [...] } } ]
},
"DepartureTime": "string",
"ArrivalTime": "string",
"OptimizeRoutingFor": "FastestRoute" | "ShortestRoute",
"MaxAlternatives": 0..6
}
| 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). |
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.
Origin DestinationDepartureTime XOR ArrivalTimeTollRoads Ferries ControlledAccessHighways DirtRoadsTravelMode LegGeometryFormat Locale OptimizeRoutingFor| 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" |
{
"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" } ]
}
}
]
}
]
}
| 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) |
•
/api/v2/routes/calculate = native passthrough — body langsung shape v2 (Origin/Destination/Waypoints[].Position). Try-It panel ini pakai endpoint ini.•
/api/routes/calculate = v0-shape adapter — terima body shape v0 lama (DeparturePosition/DestinationPosition/WaypointPositions) lalu translate ke v2 internally. Dipakai home page untuk backward compat.
{
"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
}
{
"Summary": { "Distance": 5.2, "DurationSeconds": 720 },
"Legs": [{ "Distance": 5.2, "DurationSeconds": 720,
"Geometry": { "LineString": [[106.84,-6.20], ...] } }]
}
DeparturePosition→Origin,DestinationPosition→DestinationWaypointPositions: [[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.
{
"Origins": [ { "Position": [ number, number ] } ],
"Destinations": [ { "Position": [ number, number ] } ],
"TravelMode": "Car" | "Scooter" | "Pedestrian" | "Truck",
"RoutingBoundary": {
"Unbounded": true,
"Geometry": { "AutoCircle": { "Margin": number, "MaxRadius": number } }
},
"Avoid": {
"TollRoads": boolean,
"Ferries": boolean
},
"DepartureTime": "string",
"OptimizeRoutingFor": "FastestRoute" | "ShortestRoute"
}
| 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 |
Origins Destinations RoutingBoundaryOrigins.length × Destinations.length ≤ 700| 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" |
{
"PricingBucket": "string",
"RouteMatrix": [
[
{ "Distance": number, "Duration": number, "Error": null }
]
],
"ErrorCount": number
}
| 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. |
/api/routes/matrix (Laravel proxy).
/api/routes/matrix sekarang pakai v2 adapter di backend: terima payload v0-shape (DeparturePositions/DestinationPositions) lalu translate ke v2 (/v2/route-matrix) + adapt response balik ke v0-shape (Distance dalam km, DurationSeconds). Untuk native v2, lihat tab v2 atau panggil AWS langsung dengan API Key.
{
"DeparturePositions": [[106.84, -6.20]],
"DestinationPositions": [[106.85,-6.24], [106.86,-6.25]],
"TravelMode": "Car",
"DistanceUnit": "Kilometers"
}
{
"RouteMatrix": [[
{ "Distance": 1.2, "DurationSeconds": 240 },
{ "Distance": 2.5, "DurationSeconds": 480 }
]]
}
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.
ap-southeast-1. Action not listed in AWS Console permissions. Wait for AWS rollout or use the workaround below.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], ... ]]
}]
}]
}
OptimizeWaypoints v2 only
TSP solver — kasih AWS list of waypoints, dia kembalikan urutan optimal (ngirit jarak/waktu).
ap-southeast-1. For this feature, implement nearest-neighbor TSP yourself in JS or use a library.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
}
SnapToRoads v2 only
Snap GPS trace yang noisy ke jalan terdekat. Berguna untuk clean trip log GPS dari kendaraan.
ap-southeast-1. Not yet rolled out for GrabMaps provider.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] }
]
}
GetStyleDescriptor
Return MapLibre style spec JSON. URL ini langsung ditaroh di property style waktu inisialisasi MapLibre map.
| 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. |
Standard + Light/Dark ✓Monochrome + Light/Dark ✓Hybrid/Satellite + color-scheme ❌| 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" |
{
"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.
- Pakai
{MapName}custom resource (harus dibuat dulu di Console) - Tidak ada
color-scheme/political-viewparam - 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.
| Param | Type | Note |
|---|---|---|
{Style} | path | Standard | Monochrome | Hybrid | Satellite |
{ColorScheme} | path | Light | Dark | Default |
{Variant} | path | Default (for now) |
{z}/{x}/{y} | path int | Tile coordinate (z 0-22, x/y per zoom level) |
key | query | API key |
| Status | Trigger | Note | |
|---|---|---|---|
| 400 | z/x/y out of valid range | E.g. y | Mis. y > 2^z - 1 | gt; 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 |
| 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 |
⬆️ Klik Open untuk download tile. Vector PBF (Standard/Monochrome) terlihat sebagai binary file. Raster (Satellite/Hybrid) terlihat sebagai gambar.
- 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.
| 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. |
application/x-protobuf — binary PBF berisi font glyphs. Di-decode sama MapLibre untuk render label di map.
| 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 |
- 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.
| 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 |
| 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 |
- 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.
ap-southeast-1. Maps Actions in Console only has GetTile. Workaround: screenshot from MapLibre canvas.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
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.
{
"QueryText": "string",
"QueryId": "string",
"MaxResults": number,
"BiasPosition": [ number, number ],
"Filter": {
"BoundingBox": [ number, number, number, number ],
"Circle": {
"Center": [ number, number ],
"Radius": number
},
"IncludeCountries": [ "string" ]
},
"AdditionalFeatures": [ "string" ],
"Language": "string",
"PoliticalView": "string",
"IntendedUse": "string",
"NextToken": "string"
}
| Field | Type | Required | Note |
|---|---|---|---|
QueryText |
string | YES* | Free-form keyword (1-200 char). *Required: one of QueryText or QueryId. |
QueryId |
string | — | Alternative: ID from a previous Suggest result |
MaxResults |
number | — | 1–20, default 20 |
BiasPosition |
[lng, lat] | — | 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> | — | Contact | TimeZone | Phonemes | Access |
Language |
string | — | BCP 47 (e.g. id, en) |
PoliticalView |
string | — | ISO-3 country code (e.g. IDN) |
IntendedUse |
string | — | SingleUse (default) | Storage |
NextToken |
string | — | Pagination cursor |
QueryText
OR
QueryId
BiasPosition
XOR
Filter.BoundingBox
XOR
Filter.Circle
💡 Trade-off:
·
BiasPosition → ranking-bias + Distance field in response
·
Filter.Circle / BoundingBox → hard geographic cut-off but no Distance (empirical in ap-southeast-1)
Filter.IncludeCountries
+
BiasPosition/Circle/BoundingBox
MaxResults
Language
PoliticalView
AdditionalFeatures
IntendedUse
NextToken
| 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 |
{
"PricingBucket": "string",
"NextToken": "string",
"ResultItems": [
{
"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 ],
"Distance": number,
"Categories": [ { "Id": "string", "Name": "string", "Primary": boolean } ],
"TimeZone": { "Name": "string", "OffsetSeconds": number }
}
]
}
| 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) |
{
"Text": "halte TJ",
"BiasPosition": [106.84, -6.20],
"MaxResults": 10,
"FilterCountries": ["IDN"]
}
{
"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
}
]
}
- Field
Text→QueryText FilterCountries→Filter.IncludeCountries- Response:
Results[].Place.Geometry.Point→ResultItems[].Position MaxResultsmax 10 (v2: 20)- Must create
PlaceIndexresource first in AWS Console
Suggest
Type-ahead autocomplete — return Place hits + Query refinement. Pakai untuk dropdown live di search bar.
{
"QueryText": "string",
"MaxResults": number,
"BiasPosition": [ number, number ],
"Filter": {
"BoundingBox": [ number, number, number, number ],
"Circle": { "Center": [ number, number ], "Radius": number },
"IncludeCountries": [ "string" ]
},
"AdditionalFeatures": [ "string" ],
"Language": "string",
"PoliticalView": "string",
"MaxQueryRefinements": number,
"IntendedUse": "string"
}
| Field | Type | Required | Note |
|---|---|---|---|
QueryText | string | YES | 1–200 char. Partial keyword OK (autocomplete). |
MaxResults | number | — | 1–10, default 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 |
MaxQueryRefinements | number | — | Max items with SuggestResultItemType=Query |
Language | string | — | BCP 47 (e.g. id) |
AdditionalFeatures | array | — | 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). |
Position by default. Kirim "AdditionalFeatures": ["Core"] untuk dapat lat/lng tiap suggestion — supaya bisa compute distance dari current marker/map center langsung di client.
QueryTextBiasPosition XOR Filter.BoundingBox XOR Filter.CircleSuggestResultItemTypeMaxResults Language PoliticalView MaxQueryRefinements| 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 > 10 | "...less than or equal to 10" |
| 403 | Action geo-places:Suggest tidak di-grant | "explicit deny" |
{
"PricingBucket": "string",
"ResultItems": [
{
"Title": "string",
"SuggestResultItemType": "Place" | "Query",
"Highlights": { "Title": [...] },
"Place": {
"PlaceId": "string",
"PlaceType": "string",
"Address": { "Label": "string" },
"Position": [ number, number ],
"Distance": number,
"Categories": [ ... ]
},
"Query": { "QueryId": "string", "QueryType": "string" }
}
]
}
| 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 |
/api/places/suggestions (Laravel proxy). API key di server.
{
"Text": "halte tj",
"BiasPosition": [106.84, -6.20],
"MaxResults": 5,
"FilterCountries": ["IDN"]
}
{
"Summary": { "Text": "halte tj" },
"Results": [
{ "Text": "Halte Transjakarta Halimun", "PlaceId": "AQABA..." }
]
}
Text→QueryTextFilterCountries→Filter.IncludeCountriesResults[].Text→ResultItems[].Title- v0 tidak return Position di Suggest — harus call GetPlace
ReverseGeocode
Koordinat → alamat terdekat.
{
"QueryPosition": [ number, number ],
"QueryRadius": number,
"MaxResults": number,
"Filter": {
"IncludePlaceTypes": [ "string" ]
},
"AdditionalFeatures": [ "string" ],
"Language": "string",
"PoliticalView": "string",
"IntendedUse": "string"
}
| Field | Type | Required | Note |
|---|---|---|---|
QueryPosition | [lng, lat] | YES | Coordinate point to reverse-geocode |
QueryRadius | number | — | Search radius (meters), default 0 (exact point) |
MaxResults | number | — | 1–4, default 1 |
Filter.IncludePlaceTypes | array | — | Locality | Street | PointAddress | Block | dst. |
AdditionalFeatures | array | — | TimeZone | Access |
Language | string | — | BCP 47 |
QueryPositionFilter.IncludePlaceTypesStreet atau PointAddress aja, tanpa Locality/District.| Status | Trigger | AWS Message |
|---|---|---|
| 400 | Tanpa QueryPosition | "QueryPosition is required" |
| 400 | Format [lat, lng] (terbalik) | Hasil aneh — AWS treat sebagai [lng, lat] |
| 400 | MaxResults > 4 | "...less than or equal to 4" |
{
"PricingBucket": "string",
"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 ]
}
]
}
| 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. |
/api/places/reverse (Laravel proxy).
{
"Position": [106.84, -6.20],
"MaxResults": 1
}
Position→QueryPosition- Tidak ada
Filter.IncludePlaceTypesdi v0 - Wajib bikin
PlaceIndexresource dulu
GetPlace
Detail lengkap Place by PlaceId (dari hasil Search/Suggest sebelumnya).
| Param | Type | Required | Note |
|---|---|---|---|
{PlaceId} | path | YES | Path segment (URL-encoded). From SearchText/Suggest. |
key | query | YES | API key |
additional-features | query | — | Comma-separated: TimeZone,Contact,Hours,Phonemes,Access |
language | query | — | BCP 47 (e.g. id, en) |
political-view | query | — | ISO-3 country code |
intended-use | query | — | SingleUse | Storage |
PlaceId (path)TimeZone Contact Hours Phonemes Access| Status | Trigger | AWS Message |
|---|---|---|
| 404 | PlaceId tidak ditemukan / expired | "Place not found" |
| 400 | additional-features berisi value yang gak disupport region | "Unsupported AdditionalFeatures..." |
| 403 | API Key tidak punya geo-places:GetPlace | "explicit deny" |
{
"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 }
}
PlaceId dulu dari Try it Live SearchText/Suggest, copy hasil ResultItems[0].PlaceId, paste ke sini.
- Path beda:
/places/v0/indexes/{Idx}/places/{PlaceId} - Tidak ada
additional-featuresparam 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.
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": { ... }
}]
}
Position — must call GetPlace per item if you need coordinates. For finding POIs, Suggest is more efficient (returns Position directly).
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.
ap-southeast-1. Workaround: use SearchText with structured QueryText.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 }
}]
}
SearchNearby v2 only
Find POI dalam radius dari satu titik, opsional filter by category. Tidak butuh QueryText — cuma "tunjukin yang dekat tipe X".
ap-southeast-1. Workaround: use SearchText with Filter.Circle + category keyword in QueryText.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 }]
}]
}
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 |
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 | v2 |
|---|---|---|
| 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 |
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}