Autocomplete
Build search-as-you-type UIs with Plaza's geocoding autocomplete endpoint.
Endpoint
Section titled “Endpoint”POST /api/v1/geocode/autocompleteFast partial matches as the user types. Designed for search boxes, not batch processing.
Request body
Section titled “Request body”| Field | Type | Default | Description |
|---|---|---|---|
q | string | — | Required. Partial query string. |
limit | int | 20 | Max results (1–1,000). |
focus | object | — | GeoJSON Point geometry. Results near this coordinate rank higher ({"type": "Point", "coordinates": [lng, lat]}). |
country_code | string | — | ISO 3166-1 alpha-2 code. Restrict results to one country. |
layer | string | — | Filter by type: address, poi, admin. |
lang | string | — | BCP 47 language tag for result names (e.g. de, ja, en). |
Basic request
Section titled “Basic request”curl -X POST https://plaza.fyi/api/v1/geocode/autocomplete \ -H "Content-Type: application/json" \ -H "x-api-key: $PLAZA_API_KEY" \ -d '{"q": "berlin alex", "limit": 5}'{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [13.4132, 52.5219] }, "properties": { "osm_id": 2864025, "osm_type": "node", "display_name": "Alexanderplatz", "score": 18.3, "source": "bm25", "category": "place", "subcategory": "square" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [13.4119, 52.5233] }, "properties": { "osm_id": 4597668, "osm_type": "way", "display_name": "Alexanderstraße", "score": 12.1, "source": "bm25", "category": "highway", "subcategory": "residential" } } ]}How it differs from /geocode
Section titled “How it differs from /geocode”Autocomplete uses prefix matching and skips address interpolation and deep synonym expansion. Less precise, but under 50ms.
Use autocomplete while typing. On selection or enter, hit /geocode for the final, authoritative result.
Implementation pattern
Section titled “Implementation pattern”TypeScript
Section titled “TypeScript”import Plaza from "@plazafyi/sdk";
const client = new Plaza();
let debounceTimer: ReturnType<typeof setTimeout>;
function onSearchInput(value: string) { clearTimeout(debounceTimer); if (value.length < 2) return;
debounceTimer = setTimeout(async () => { const suggestions = await client.v1.geocode.autocomplete({ q: value, limit: 5, focus: { type: "Point", coordinates: [userLng, userLat] }, }); renderSuggestions(suggestions.features); }, 200);}
async function onSuggestionSelect(text: string) { const result = await client.v1.geocode.forward({ q: text, limit: 1 }); const [lng, lat] = result.features[0].geometry.coordinates; map.flyTo({ center: [lng, lat], zoom: 16 });}Python (FastAPI backend)
Section titled “Python (FastAPI backend)”import plazafrom fastapi import FastAPI, Query
app = FastAPI()client = plaza.Client()
@app.get("/api/search-suggestions")def suggestions(q: str = Query(min_length=2), lat: float = None, lng: float = None): params = {"q": q, "limit": 5} if lat is not None and lng is not None: params["focus"] = {"type": "Point", "coordinates": [lng, lat]} results = client.v1.geocode.autocomplete(**params) return [ {"name": f.properties["display_name"], "coords": f.geometry.coordinates} for f in results.features ]results, err := client.V1.Geocode.Autocomplete(ctx, plaza.V1GeocodeAutocompleteParams{ Q: plaza.F("san fran"), Limit: plaza.F(int64(5)), Focus: &plaza.GeoJSONPoint{Type: "Point", Coordinates: []float64{-122.4194, 37.7749}},})if err != nil { panic(err)}
for _, f := range results.Features { fmt.Println(f.Properties.DisplayName)}Debounce timing
Section titled “Debounce timing”Debounce at 150–300ms depending on your audience:
- 150ms — Fast typists, desktop apps, low-latency connections
- 200ms — Good default for web apps
- 300ms — Mobile apps, users on slower connections
Skip queries under 2 characters — single-letter queries waste quota with irrelevant results.
Always pass a focus point. Autocomplete with no geographic context returns unpredictable results. “Par” could be Paris, Paramaribo, or a park in Portland. With a focus point near France, Paris wins immediately.
Set country_code for country-specific apps. If your users are all in one country, lock it down. Fewer ambiguous results, faster responses.
Cache aggressively on the client. If the user types “ber”, gets results, then types “berl”, the “ber” results are still valid suggestions. Cache autocomplete responses keyed by query prefix and reuse them while waiting for the next response.
Cancel in-flight requests. When a new keystroke arrives, abort the previous autocomplete request. Stale responses arriving out of order cause flickering in the dropdown. Use AbortController in JavaScript or context cancellation in Go.