--- title: Autocomplete | Plaza Docs description: Build search-as-you-type UIs with Plaza's geocoding autocomplete endpoint. --- ## Endpoint ``` POST /api/v1/geocode/autocomplete ``` Fast partial matches as the user types. Designed for search boxes, not batch processing. ## 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 Terminal window ``` 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` 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`](/guides/geocoding/index.md) for the final, authoritative result. ## Implementation pattern ### TypeScript ``` import Plaza from "@plazafyi/sdk"; const client = new Plaza(); let debounceTimer: ReturnType; 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) ``` import plaza from 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 ] ``` ### Go ``` 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 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. ## Tips **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.