---
title: "Autocomplete — search-as-you-type place suggestions"
method: GET
path: "/v1/autocomplete"
tags: ["Geocoding"]
---

# Autocomplete — search-as-you-type place suggestions

`GET /v1/autocomplete`

## Request

- Base URL: `https://geo.thinair.co`
- URL: `https://geo.thinair.co/v1/autocomplete`
- Auth: HTTP bearer

Purpose-built typeahead: partial input → ranked place suggestions at per-keystroke latency. Edge-cached on normalized prefix (24h) — repeat prefixes are served sub-50ms with `X-Cache: HIT`. Pass `focus_lat`/`focus_lon` for proximity-biased, distance-guarded results, or `boundary_country`/`bounds` for hard filters. Free tier. For full geocoding (addresses, intersections, confidence ladder) use /v1/geocode.

## Query parameters

- `text` string, required: Partial input under the user's cursor. Fires from 2 characters when the request is scoped (focus/bounds/country), or 3 characters for a global query; shorter inputs return an empty result with a `min_length` warning (HTTP 200 — no engine call, so a bare 1-char never hits the engine).
- `focus_lat` number, nullable: Latitude of the proximity bias point. When set (with focus_lon), results are biased toward it AND results farther than ~500 km are dropped unless nothing is within range.
- `focus_lon` number, nullable: Longitude of the proximity bias point.
- `boundary_country` string: ISO 3166-1 alpha-2 or alpha-3 country code — hard filter.
- `bounds` string: Bounding-box hard filter as `minLon,minLat,maxLon,maxLat` (WGS84 degrees).
- `layers` string: Comma-separated layer filter: venue, street, address, intersection, locality, neighbourhood, borough, county, localadmin, region, country, postalcode, coarse. Unknown layers are ignored.
- `size` integer: Maximum suggestions to return (1–10). Default 5.
- `lang` string: Preferred label language (ISO 639-1 / BCP47), passed through to the engine.

## Response `200`

Ranked suggestion list. `X-Cache: HIT|MISS` reports edge-cache status.

- AutocompleteResponse
  - `items` AutocompleteItem[], required
    - `id` string: Stable public ThinAir id (`ta_place_<key>` / `ta_intersection_<key>`). Resolvable via `GET /v1/place`.
    - `name` string
    - `label` string
    - `layer` string
    - `confidence` number
    - `lat` number, required
    - `lon` number, required
    - `country_code` string
    - `locality` string
    - `region` string
    - `distance_km` number
  - `meta` object, required
    - `query` string, required
    - `upstream_ms` number, required
    - `item_count` number, required
    - `cacheHit` boolean
    - `cacheHitKind` 'v3_hit' | 'legacy_dual_read': AC_L1_V3 only: `v3_hit` when the coarse `ac:v3` key served the answer; `legacy_dual_read` when a warm `ac:v2` entry was served via the dual-read fallback. Omitted when the flag is OFF or the answer was not a positive-cache HIT.
    - `source` string: Where the answer came from: `engine` (live upstream), `cache` (edge prefix cache), `prefilled_cache` (curated/prewarmed entry), or `edge_hotset` (the L(-1) in-isolate runtime hot-set for 1-2 char input). Absent on the degraded/empty paths: below-floor short inputs, negative-cache hits, and timeout-degraded responses.
    - `cacheTier` 'l0' | 'kv' | 'edge': Present only on a hit from the L(-1) runtime hot-set (`edge`) — drives `X-Cache: HIT-EDGE`. Omitted on every other response.
  - `warnings` string[]: Soft signals: `min_length` (input below the engine floor — 3 chars global, 2 chars when scoped by focus/bounds/country; engine skipped), `focus_distance_filtered` (far results dropped), `no_results_near_focus` (nothing within ~500 km of focus; honest unfiltered set returned), `country_filtered` (a result outside `boundary_country` was dropped by the hard-filter backstop), `bounds_filtered` (a result outside `bounds` was dropped by the rect backstop), `no_focus_ambiguous` (no focus/bounds/country given and the top result's country differs from the caller's geo-IP country), `short_final_token_dropped` (a 1-char final token was stripped from the engine query; the full text is still echoed in `meta.query`), `negative_cached` (served from the short-TTL timeout/empty negative cache), `upstream_degraded` (that negative entry recorded a recent engine timeout), `autocomplete_more_context_required` (2-char input without focus/bounds/country — add one to enable suggestions at this length), `autocomplete_cache_only` (1-char input — served from the prefilled cache only, never the engine), `autocomplete_timeout` (engine exceeded the per-call ceiling; degraded to an empty 200).

## Other responses

- `400`: Invalid query parameters.
- `429`: Quota exceeded or rate-limited.
- `502`: Upstream engine unavailable.

---

[API](https://skmtc.dev/thinair/apis/thinair-geo-api.md) · [All operations](https://skmtc.dev/thinair/apis/thinair-geo-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thinair/apis/thinair-geo-api/revisions/8fac2d5e4b34?raw)
