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

qstring

Free-text place query. Required unless at least one structured component (street, housenumber, city, postcode, country) is supplied

streetstring

Structured 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

housenumberstring

Structured component: house number, e.g. 10 or 221B. See street for how structured components behave on each backend, with one difference on the first-party index: the number is matched against the answer rather than required of the index's raw housenumber field, because a great many records carry their number in their NAME instead ("10 Downing Street" as a place in its own right) and requiring the field excluded exactly those. It is still a filter where the data can satisfy it (asking for number 3 does not return number 1), but where NOTHING on the page carries the number, the page is returned with match.components.housenumber: "unmatched" on every row rather than emptied. An empty page is the least useful answer available and says nothing about why it is empty. matched means the record's housenumber field, or the leading token of its name, is the number asked for; inferred means it carries a different one

citystring

Structured 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

postcodestring

Structured 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

countrystring

ISO 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

matchboolean

Ask 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

limitinteger

Maximum results, 1–10 (Photon default when omitted)

langstring

Result 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

biasstring

Location bias as lon,lat (WGS84), e.g. -0.1278,51.5074

zoominteger

Map 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

bboxstring

Hard 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

Response

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 required

Changes

No recorded changes to this operation across all 1 revision of this API.