---
title: "`GET /geocode?q=<text>&limit=<n≤10>&lang=<code>&bias=<lon>,<lat>&bbox=<minLon>,<minLat>,<maxLon>,<maxLat>&country=<cc>[,<cc>…]`."
method: GET
path: "/geocode"
tags: ["geocoding"]
---

# \`GET /geocode?q=<text>&limit=<n≤10>&lang=<code>&bias=<lon>,<lat>&bbox=<minLon>,<minLat>,<maxLon>,<maxLat>&country=<cc>\[,<cc>…\]\`.

`GET /geocode`

## Request

- Base URL: `https://api.mapmap.ai`
- URL: `https://api.mapmap.ai/geocode`
- Auth: one of:
  - HTTP bearer
  - API key in query parameter `api_key`

## Query parameters

- `q` string
- `street` string
- `housenumber` string
- `city` string
- `postcode` string
- `country` string
- `match` boolean
- `limit` integer
- `lang` string
- `bias` string
- `zoom` integer
- `bbox` string

## Response `200`

Photon-compatible GeoJSON FeatureCollection (locality-aware reranked, entity-deduplicated: one row per real-world place). First-party hits carry a stable `id`; POI hits add a `details` object of whitelisted OSM display tags (opening_hours, phone, website, brand, cuisine, wheelchair, wikidata, socket:*, …). Two query fast paths: a pasted coordinate pair (`51.5074, -0.1278`) returns a single `type: "coordinate"` feature at that point labelled with the nearest address; a pure category query (`coffee`, `petrol station`, `pharmacy`) with a `bias` returns the nearest POIs of that category; a browse with `distance_m` on each hit, not a name match. When any structured component is supplied (or a free-text query passes `match=true`), every hit additionally carries a `match` object (see the `GeocodeMatch` schema): a per-component `matched`/`inferred`/`unmatched` verdict, the `score_gap` between the top answer and its runner-up, and which backend answered. A bare city or town query (no comma) whose top answer is that settlement carries up to three of the city's transport hubs directly behind it: airports with an IATA code within 60 km, then railway stations within 25 km, each named for the city (on either backend, given a first-party index). First-party index only: each hit's `state` is the first-level subdivision (admin level 4) that contains it, from the administrative-boundary database when one is configured; and a UK postcode typed in `q` (a full postcode anywhere in it, or an outward code as its final token) anchors the ranking on that postcode district when no `bias` is sent, never on a structured request

- object

## Other responses

- `400`: Neither `q` nor any structured component, a multi-country `country` with nothing to narrow, a malformed parameter (including a `country` naming no country), or an unsupported `lang` (`urn:sn-gateway:problem:unsupported-lang`, body lists `supported_langs`)
- `401`: Missing or invalid API key
- `429`: Quota or rate limit exceeded
- `501`: Geocoding not enabled (neither SN_GEOCODE_DIR nor SN_PHOTON_URL set), or `q` combined with structured components on a Photon-proxy-only deployment (`urn:sn-gateway:problem:structured-search-not-enabled`: clients feature-detect on this status)
- `502`: Photon upstream failed

---

[API](https://skmtc.dev/mapmap/apis/sn-gateway.md) · [All operations](https://skmtc.dev/mapmap/apis/sn-gateway/llms.txt) · [OpenAPI document](https://skmtc.dev/mapmap/apis/sn-gateway/revisions/2293be8b4c38?raw)
