Skip to content

50,000 free calls a month, card-free. Get an API key →

Documentation menu
docs / api / get-geocode
geocoding

GET/geocode

API key required, sent as Authorization: Bearer snk_… or ?api_key=snk_….

Call it

bash
curl -fsS -X GET "https://api.mapmap.ai/geocode" \
  -H "Authorization: Bearer $MAPMAP_KEY"

Parameters

NameInRequiredDescription
qquerynoFree-text place query. Required unless at least one structured component (street, housenumber, city, postcode, country) is supplied
streetquerynoStructured component: street name, e.g. Downing Street. Matches the street context of addresses and POIs (including transliterated street alternatives) and the name of the street itself. On the first-party index every structured component is a REQUIRED clause (it excludes non-matching results outright, it does not merely reorder them) and may be combined with q, which then drives ranking within what the components allow. On a Photon-proxy-only deployment, structured components are pushed down to Photon's own /structured endpoint, which takes no free text: combining them with q there answers 501 structured-search-not-enabled rather than silently dropping half the request
housenumberquerynoStructured component: house number, e.g. 10 or 221B. See street for how structured components behave on each backend
cityquerynoStructured component: town or city, e.g. London. Matches the locality context, which carries the containing city and romanised context forms as well as the locality proper. See street
postcodequerynoStructured component: postcode in any spacing or case, e.g. SW1A 2AA or sw1a2aa: normalised the way the index stored it, so both are one query. A bare UK outward code (SW1A) selects the whole district. See street
countryquerynoISO 3166-1 alpha-2 code or country name (GB, gb, United Kingdom, UK all resolve to the same code), or a comma-separated list of them, e.g. GB,IE. A single value is a structured component (see street). Any value is also a hard filter on free-text search: every returned feature's countrycode is one of the countries named, on both backends (the first-party index filters in the query; the Photon proxy path fetches a deeper page and filters the answer, so limit counts what survives). A value naming no country is a 400 rather than a filter that silently matches nothing. Ignored by the two fast paths that run before any text search: a pasted coordinate pair and a category browse. A multi-country value on its own, with no q and no other component, is a 400: a filter needs a search to narrow
matchquerynoAsk a plain free-text query for the match object on every hit (score_gap and source; components is empty without structured input). Implied, and not needed, whenever any structured component is supplied
limitquerynoMaximum results, 1–10 (Photon default when omitted)
langquerynoResult language. Must be one of the deployment's supported languages (SN_PHOTON_LANGS, default en, de, fr) or default; any other value is a 400 unsupported-lang problem listing the supported set
biasquerynoLocation bias as lon,lat (WGS84), e.g. -0.1278,51.5074
zoomquerynoMap zoom (0-20) controlling bias strength: zoomed in favours nearby results, zoomed out favours prominence. Only meaningful with bias; defaults to a gentle city-scale bias
bboxquerynoHard bounding-box filter as minLon,minLat,maxLon,maxLat (WGS84, GeoJSON bbox axis order: the same convention as Mapbox/Google/HERE bbox/bounds parameters), e.g. -0.489,51.286,0.236,51.686 for Greater London. Every returned feature's coordinate must fall inside the box; unlike bias (a ranking preference) this can exclude an otherwise-top-ranked result outright. minLat must be ≤ maxLat. minLon may be greater than maxLon to describe a box that crosses the antimeridian (per RFC 7946 §5): e.g. 170,-20,-170,-15; both minLon and maxLon must still be within [-180, 180]. Applies to free-text search on either backend (the first-party index filters in the query; the Photon proxy path pushes the box upstream where that is safe, fetches a deeper page, and filters the answer regardless). Ignored by the two fast paths that run before any text search: a pasted coordinate pair still returns that point, and a category browse (coffee + bias) still browses around the bias

Responses

200Photon-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
400Neither 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)
401Missing or invalid API key
429Quota or rate limit exceeded
501Geocoding 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)
502Photon upstream failed

Error bodies follow the shared problem model documented on API conventions.

Also under geocoding

Generated from https://api.mapmap.ai/openapi.json on 2026-09-17 · operationId get_geocode