Search API
Find places by name or address, or look up what is at a coordinate.
Search is available on paid plans only — Starter, Pro and Enterprise. A free-plan key gets 403 on /search, /search/structured and /reverse; see Errors for the exact response and Pricing for the plans.
| Billing | 1 unit per request (/search, /search/structured and /reverse alike) |
| Data | OpenStreetMap, powered by Photon |
| Coverage | Europe |
| Plan | Paid plans only (Starter, Pro, Enterprise). Free-plan keys get 403. |
| Languages | cs, en, sk, pl, de, or default for each place’s local name |
| Format | GeoJSON FeatureCollection, coordinates as [lon, lat] |
Search
Find places by name or address. Built for search-as-you-type: send a request on every keystroke (debounced) and partial words still match.
GET /search?q={query}&apiKey=<key>Parameters
| Parameter | Description |
|---|---|
q | Search text (required) |
limit | Maximum number of results (default 15, max 50) |
lang | Result language: cs, en, sk, pl, de, or default for local names. Without lang, the Accept-Language header decides, so browsers get their user’s language when it is supported. Any other value returns HTTP 400. |
lat, lon | Prefer results near this point (location bias) |
zoom, location_bias_scale | How strongly to apply the location bias: a lower zoom (default 12, roughly a map zoom) covers a wider area, and location_bias_scale (0.0–1.0, default 0.4) sets how much prominence counts against distance |
bbox | Only return results inside minLon,minLat,maxLon,maxLat |
osm_tag | Filter by OSM tag, repeatable: key:value, key, :value, or negated with ! (e.g. osm_tag=natural:peak, osm_tag=!highway) |
layer | Filter by type, repeatable: house, street, locality, district, city, county, state, country, other |
countrycode | Only return results in this ISO 3166-1 alpha-2 country; repeat for several (countrycode=CZ&countrycode=SK) |
dedupe | Set 0 to keep duplicate results (such as one street split into several OSM ways) |
Example
GET https://api.mapriot.com/search?q=Ještěd&osm_tag=natural:peak&lang=en&limit=1&apiKey=<key>Response
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"osm_type": "N",
"osm_id": 308351899,
"osm_key": "natural",
"osm_value": "peak",
"type": "other",
"name": "Ještěd",
"city": "Liberec",
"county": "okres Liberec",
"state": "Liberec Region",
"country": "Czechia",
"postcode": "460 08",
"countrycode": "CZ"
},
"geometry": { "type": "Point", "coordinates": [14.9839199, 50.7327738] }
}
]
}Areas such as cities, streets, and parks also include extent: [minLon, maxLat, maxLon, minLat]. Use it to fit the map to the result.
Structured search
Search by address fields instead of free text.
GET /search/structured?city=Brno&street=Masarykova&housenumber=1&apiKey=<key>Fields: countrycode, state, county, city, postcode, district, street, housenumber. The common parameters limit, lang, lat/lon, bbox, osm_tag and layer also work here.
Reverse geocoding
Find the nearest place to a coordinate.
GET /reverse?lat={lat}&lon={lon}&apiKey=<key>| Parameter | Description |
|---|---|
lat, lon | Coordinate (required) |
radius | Search radius in km |
limit | Maximum number of results (default 1, max 50) |
lang, osm_tag, layer | Same as for search |
Example
GET https://api.mapriot.com/reverse?lat=50.0875&lon=14.4213&lang=en&apiKey=<key>{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"osm_type": "W", "osm_id": 340086966,
"osm_key": "tourism", "osm_value": "attraction", "type": "house",
"name": "Prague Meridian", "street": "Old Town Square", "district": "Josefov",
"city": "Prague", "postcode": "110 00", "country": "Czechia", "countrycode": "CZ"
},
"geometry": { "type": "Point", "coordinates": [14.4213299, 50.0874765] }
}
]
}Add layer=street to get the nearest street instead of the nearest point of interest.
Autocomplete from a browser
Search is a plain GET, so browsers send it without a CORS preflight. Debounce keystrokes and bias the results towards the visible map:
let timer;
input.addEventListener('input', () => {
clearTimeout(timer);
timer = setTimeout(async () => {
const { lng, lat } = map.getCenter();
const params = new URLSearchParams({
q: input.value, limit: '5', lang: 'en',
lat: String(lat), lon: String(lng), zoom: String(Math.round(map.getZoom())),
apiKey: '<key>',
});
const res = await fetch(`https://api.mapriot.com/search?${params}`);
const { features } = await res.json();
// features[i].geometry.coordinates is [lon, lat]
}, 250);
});Each request costs 1 unit, so a 250 ms debounce keeps a typical search at 3–5 units.
Errors
| Status | Cause |
|---|---|
400 | Invalid parameter, such as an unsupported lang, a missing q, or an unknown parameter. The body is JSON naming the parameter, e.g. {"lang": [{"message": "Language is not supported. Supported are: default, cs, de, sk, en, pl, es", "value": "fr"}]} |
403 | Missing, invalid, or restricted API key — or search is not included in your plan (free plan). Plain-text body: This feature is not available on your plan. See https://mapriot.com/pricing for details or contact us at support@mapriot.com. A rejected request is not billed. |
429 | Free-tier hard cap reached (200% of the monthly limit) |
Responses are cacheable for 5 minutes (Cache-Control: public, max-age=300).