# geosearch API

UK place search: towns, villages, streets, postcodes, rivers, canals and points of interest (shops, pubs, hospitals, schools and so on). It's typo-tolerant and understands "thing in place" queries like "pubs in n5". Responses typically take a few milliseconds on the server.

This is a proof of concept. Keys come from Dan Hartropp (dan@danhartropp.com).

Base URL: `https://geosearch-tlm25zrwea-nw.a.run.app`
Auth: header `X-API-Key: <key>` on every request.
Limits: 600 requests a minute per key, with short bursts. A 429 response carries `Retry-After`.
Attribution: every response has an `attribution` string. Show it wherever you show results.

## GET /search

Find places from free text.

Parameters:
- `q` (required): the query, e.g. `manchestr`, `hospital in leeds`, `N5 1XL`, `Church Lane, Stowmarket`.
- `limit`: 1–50, default 10.
- `lat`, `lon`: optional, together. They prefer results near this point for queries that don't name a place ("pubs", "tesco", "pubs near me"). A query that names a place ignores them.
- `geometry=true`: adds line geometry (GeoJSON MultiLineString) for streets, rivers and canals. Lines can be large; ask only when you'll draw them.

Response:
```json
{
  "query": "newport",
  "results": [
    {"name": "Newport", "kind": "settlement", "county": "Casnewydd - Newport",
     "lat": 51.5879, "lon": -2.9967, "answer": true}
  ],
  "more": true,
  "confidence": 0.92,
  "attribution": "…"
}
```

Result fields: `name`, `kind` (settlement, street, poi, feature, address, district, county, country, postcode), `category` (for POIs, e.g. "pub"), `town`, `county`, `lat`, `lon`, `answer` (true for right answers, which come first), `primary_name` (the other-language name where there is one), `geometry` (only with `geometry=true`).

Response fields: `results`; `confidence` (0–1, how likely the first result is right; above 0.7 it reads as a probability); `more` (true when more right answers exist than were returned); `near` (the postcode used for `lat`/`lon`, when they were applied); `postcode` (when the query was a postcode).

How to read results:
- Take the first result with `answer: true`.
- When several `answer: true` results share the same name in different places, they're equally good places with the same name, so ask the user which one they meant. Take `kind` into account: "nottingham" ties the city with pubs called The Nottingham, and the city is usually what's meant.
- With no `answer: true` results, show the results as suggestions.

## GET /suggest

Autocomplete as the user types (from about 3 characters). It matches the start of names, so it's quicker but less forgiving than /search; run /search on Enter.

Parameters: `q` (required), `limit` 1–20 (default 10), `lat` + `lon`.
Response: `{"query": "nott", "results": [{"name": "Nottingham", "kind": "settlement", "county": "City of Nottingham", "lat": 52.956, "lon": -1.151}], "attribution": "…"}`

## GET /reverse

What's at a point.

Parameters: `lat`, `lon` (required, within Great Britain and Northern Ireland), `kind` (comma list of settlement, street, feature, poi; default all), `limit` 1–50.
Response: `postcode` (nearest, with `distance_m`), `areas` (`built_up_area`, `parish`, `ward`, `district`, `county`, `country`), `settlement`, `street`, and `results` (nearby places with `distance_m`).

## Errors

`{"error": "message"}` with status 400 (bad parameter), 401 (missing or unknown key), 403 (key not allowed from this website), 429 (rate limit; see `Retry-After`), 503 (search took too long; retry).

## Examples

```sh
curl -s 'https://geosearch-tlm25zrwea-nw.a.run.app/search?q=lufbra&limit=3' -H 'X-API-Key: YOUR_KEY'
```

```js
const res = await fetch('https://geosearch-tlm25zrwea-nw.a.run.app/search?q=' + encodeURIComponent(q), {
  headers: { 'X-API-Key': KEY },
});
const { results, attribution } = await res.json();
```

```python
import requests
r = requests.get("https://geosearch-tlm25zrwea-nw.a.run.app/search",
                 params={"q": "pubs", "lat": 53.80, "lon": -1.55, "limit": 10},
                 headers={"X-API-Key": KEY})
```

Full OpenAPI spec: https://geosearch-tlm25zrwea-nw.a.run.app/openapi.yaml
