Guides
MapsPlatformMCP quickstart
Put a Navo map on a page, add place search and reverse geocoding, and show ports, airports and rail terminals. MapLibre, Leaflet and plain HTTP.
MapsPlatformMCP has two parts that share one place database.
| Part | What it gives you | Base path |
|---|---|---|
| Places API | Place search, address and postal lookup, reverse geocoding, place details | https://api.navo24.com/v1/geo/ |
| Maps API | Vector tiles, three map styles, fonts, icons, a logistics hubs layer | https://api.navo24.com/v1/maps/ |
The place database holds 5.9 million cities, regions, ports, airports, rail stations and logistics sites, with UN/LOCODE, IATA, ICAO, UIC and ESR codes and names in 568 languages. It is rebuilt every month. The basemap comes from OpenStreetMap and is refreshed with it.
The Places API needs a Navo key with the tmcp_ prefix, the same key you use for Tracking, Distance & Time and Carbon. Send it as Authorization: Bearer tmcp_... or X-API-Key. Get a key in your Navo account. Requests without a key get 401 missing_key. The Maps API (styles, tiles, fonts, hubs layer) loads without a key. Both parts are also limited to 120 requests per minute per IP.
Keep the key on your server. For type-ahead on a public page, call your own backend and let it add the key, so the key never ships to the browser.
Show a map
The styles follow the MapLibre style spec v8, so any MapLibre client renders them: MapLibre GL JS on the web, MapLibre Native on iOS and Android.
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.css">
<script src="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.js"></script>
<div id="map" style="height:480px"></div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.navo24.com/v1/maps/styles/navo-light.json',
center: [30.73, 46.48],
zoom: 6,
});
</script>
| Style | Use it for |
|---|---|
navo-light | Default product maps, tracking views, dashboards |
navo-dark | Dark interfaces and control rooms |
navo-logistics | The light map plus ports (blue), airports (violet) and rail terminals (orange) |
A live demo with a style switcher: api.navo24.com/v1/maps/demo.html.
Search for a place
/geo/search is built for type-ahead. Send what the user typed, debounce at about 150 ms, and limit the kinds you need.
curl -H "Authorization: Bearer $NAVO_KEY" "https://api.navo24.com/v1/geo/search?q=Hamburg&kinds=city,port&limit=5"
Every result has id, kind, name, country_code, lat and lng. Codes appear when the place has them: locode, iata, icao, uic, esr. A search by code works too: q=DEHAM or q=FRA.
Fly the map to the chosen place:
// server side (Node): the key stays out of the browser
const r = await fetch(`https://api.navo24.com/v1/geo/search?q=${encodeURIComponent(text)}&limit=5`, {
headers: { Authorization: `Bearer ${process.env.NAVO_KEY}` },
});
const { data } = await r.json();
map.flyTo({ center: [data[0].lng, data[0].lat], zoom: 9 });
Reverse geocoding
/geo/reverse returns the nearest places to a point, closest first. Add kinds to ask a narrower question, such as the nearest port to a warehouse.
curl -H "Authorization: Bearer $NAVO_KEY" "https://api.navo24.com/v1/geo/reverse?lat=53.54&lng=9.98&kinds=port&limit=3"
map.on('click', async (e) => {
const { lat, lng } = e.lngLat;
// /api/reverse is your backend route that calls /v1/geo/reverse with the key
const r = await fetch(`/api/reverse?lat=${lat}&lng=${lng}&limit=1`);
const { data } = await r.json();
if (data[0]) new maplibregl.Popup().setLngLat(e.lngLat).setText(`${data[0].name}, ${data[0].distance_km} km`).addTo(map);
});
Addresses and postal codes
/geo/address turns a street address into coordinates and a postcode. /geo/postal turns a postal code into a place. Pass cc with postal codes: the same code exists in many countries.
curl -H "Authorization: Bearer $NAVO_KEY" "https://api.navo24.com/v1/geo/address?q=Deribasivska%2010%20Odesa"
curl -H "Authorization: Bearer $NAVO_KEY" "https://api.navo24.com/v1/geo/postal?code=65000&cc=UA"
Logistics hubs
/maps/hubs.geojson holds the main port, airport and rail terminal of about 6,350 cities, 11,972 points in total. rank: 1 marks the main hub of each type in a city. The navo-logistics style draws the layer; with another style, add it yourself:
map.on('load', () => {
map.addSource('hubs', { type: 'geojson', data: 'https://api.navo24.com/v1/maps/hubs.geojson' });
map.addLayer({
id: 'hubs', type: 'circle', source: 'hubs',
filter: ['==', ['get', 'type'], 'port'],
paint: { 'circle-color': '#1f4fe6', 'circle-radius': 4 },
});
});
Leaflet and other clients
Leaflet has no vector renderer of its own. Use the @maplibre/maplibre-gl-leaflet plugin with the same style URL. QGIS, OpenLayers and Tangram read the TileJSON at /maps/tiles/basemap.json directly.
Attribution
Keep the attribution the style sets: ”© Navo, © OpenStreetMap”. Place data comes from GeoNames (CC BY 4.0), UN/LOCODE, OurAirports, Wikidata and OpenStreetMap (ODbL); /geo/meta lists the sources of the current build.