Map Tiles & Styles
Map Tiles & Styles
A complete, first-party basemap served by Navvo Maps. Point the Navvo Maps renderer at a style URL and everything else — vector tiles, glyphs, sprites, raster layers — is served by Navvo. The one exception is the aerial imagery in the satellite style, which the browser fetches directly from the imagery provider's CDN — see Attribution.
Scope required: tiles
x-api-key header. Pass the key as a query parameter on the style URL: ?api_key=nvvo_YOUR_KEY.api_key (query param on the style URL, or the SDK apiKey) to get a clean, unwatermarked map.Origin, so the Navvo Web SDK and tile/style URLs can be fetched from any third-party website that embeds a keyed Navvo map. Authentication is Bearer-header / api_key-based (no cookies), so open CORS is safe. Native mobile apps aren't subject to browser CORS at all.GET /tiles/styles
The catalog of available map styles — for building a style switcher. Each entry's style value is what you pass to GET /tiles/style?style=; category is base or imagery.
curl -s "https://navvo.io/api/v1/tiles/styles" -H "x-api-key: $NAVVO_API_KEY"
{
"provider": "navvo-tiles", "count": 6, "styleUrl": "/tiles/style?style={style}",
"styles": [
{ "style": "standard", "label": "Standard", "category": "base", "description": "The default road map." },
{ "style": "positron", "label": "Light", "category": "base", "description": "Minimal light basemap." },
{ "style": "dark", "label": "Dark", "category": "base", "description": "Night/dark basemap." },
{ "style": "satellite", "label": "Satellite", "category": "imagery", "description": "Aerial/satellite imagery." },
{ "style": "3d", "label": "3D Buildings", "category": "base", "description": "3D building extrusions (supports ?terrain=1)." },
{ "style": "terrain", "label": "Terrain", "category": "imagery", "description": "Shaded-relief terrain." }
]
}
GET /tiles/style
Returns a complete Navvo Maps style document (standard vector style spec, v8) for a named style. This is the URL you give the Navvo Maps renderer.
Query parameters
standard (default), road (alias of standard), positron, dark, satellite, terrain, 3d. The full list with labels is at GET /tiles/styles. Unknown values return 400.name.1/true to include the elevation terrain source in the 3d style (when available).const map = new NavvoMaps.Map({
container: "map",
style: "https://navvo.io/api/v1/tiles/style?style=standard&api_key=nvvo_YOUR_KEY",
center: [35.91, 31.95],
zoom: 12,
});
The returned style references Navvo-hosted child resources (glyphs, sprites, and the vector tile template) — all served by Navvo. You don't request these directly; the renderer loads them automatically from the style.
The vector source carries its tile template inline (tiles) rather than a url pointing at a TileJSON document. That removes one round trip before the first tile can be requested, which measurably speeds up a cold map load. GET /tiles/tilejson/navvo is still served for clients that prefer to resolve a catalog themselves:
{
"version": 8,
"name": "Navvo standard",
"sources": {
"navvo": {
"type": "vector",
"tiles": ["https://navvo.io/api/v1/tiles/vector/navvo/planet/{z}/{x}/{y}.pbf?v=<version>"],
"minzoom": 0, "maxzoom": 14,
"attribution": "© Navvo"
}
},
"layers": [
{ "id": "background", "type": "background", "paint": { "background-color": "#FAFBFC" } },
{ "id": "water", "type": "fill", "source": "navvo", "source-layer": "water", "paint": { "fill-color": "#D8E7FF" } }
],
"metadata": { "navvoStyle": "standard", "navvoAttribution": "© Navvo" }
}
satellite and terrain are hybrid styles, not single-source raster styles.
satellite= an imagery raster underlay (source idsatellite) + the Navvo vector source (navvo) floated on top for roads, street names and place labels, plus Navvoglyphsandsprite. An authenticated request returns 2 sources and 75 layers: 1 background, 1satelliteraster and 73navvovector layers.terrain= the Navvo low-zoom shaded-relief raster (source idne2_shaded,maxzoom6) under the full Navvo vector source (navvo). Authenticated: 2 sources, 110 layers. There is no third-party host and no DEM in this style.
navvo-watermark (satellite becomes 3/76, terrain 3/111). If your integration asserts on source or layer counts, key the request first — otherwise the same style will measure differently in development and production.If you filter layers by source id, expect navvo on both of these styles.
standard/dark/positron/3d are pure vector. satellite and terrain are hybrids: a raster underlay with the navvo vector source (and Navvo glyphs/sprites) drawn over it. Use /tiles/style as your single entry point.3d vector styles (standard/dark/positron), buildings render as flat 2D footprints via the buildingfill layer, which is visible by default but only appears when zoomed in (minzoom ≈ 15.5). Nothing is raised — the footprints stay flat even when the camera is pitched (e.g. during navigation).To raise buildings into 3D on those styles, add your own fill-extrusion over the same source layer:map.addLayer({
id: 'buildings-3d', type: 'fill-extrusion',
source: 'navvo', 'source-layer': 'building', minzoom: 15.5,
paint: {
'fill-extrusion-color': '#cfd5e0',
'fill-extrusion-height': ['coalesce', ['get', 'render_height'], ['get', 'height'], 6],
'fill-extrusion-base': ['coalesce', ['get', 'render_min_height'], ['get', 'min_height'], 0],
},
});
// (extrusions only read as 3D when the camera is pitched — set map.setPitch(...))
3d style ships this raised layer (navvo-3d-buildings) already, along with a pitched camera — use it when you want 3D buildings out of the box./tiles/style responses are sent with Cache-Control: public, max-age=300, stale-while-revalidate=86400. The style document is safe to reuse for 5 minutes (and served stale-while-revalidate for up to a day), so a renderer, service worker, or CDN can cache it across reloads instead of refetching on every map open. Style edits propagate within ~5 minutes.Content-Encoding: br) is preferred when Accept-Encoding includes br, falling back to gzip — every browser and standard HTTP client (and the Navvo renderer) negotiates this automatically and decompresses transparently. Brotli is typically ~10–20% smaller than gzip on vector tiles; gzip alone cuts them ~35% vs raw. Raster/imagery tiles (PNG/JPEG) are already compressed and are served as-is. Responses carry Vary: Accept-Encoding, so a shared cache stores the right variant./tiles/style and /tiles/tilejson/navvo carry a version query parameter (?v=…). Requests made with that versioned URL are answered with Cache-Control: public, max-age=31536000, immutable — the URL itself changes whenever the underlying data changes, so clients, service workers, and CDNs may cache versioned tiles for a year without revalidating. Always use the tile template exactly as returned by the style/TileJSON (don't strip the query string) to benefit. Unversioned tile requests still work and are served with max-age=86400, stale-while-revalidate=604800.ETag. It is a strong content hash at the Navvo origin, but a CDN in front of the API may re-compress the body and hand you the weak form (W/"…") instead. Always replay the exact value you received in If-None-Match — the origin compares it literally, so a weak-prefixed value it did not issue returns a full 200 body rather than 304. When the tile is unchanged and the validator matches, you get 304 Not Modified with no body — useful for lean revalidation from proxies and offline sync jobs.Attribution
Navvo serves the base map itself — vector tiles, glyphs, sprites, the shaded-relief backdrop and the DEM are all Navvo-hosted and carry © Navvo.
- Base map (
standard,dark,positron,3d,terrain):© Navvo. No third-party attribution is required. - Satellite imagery (
satellitestyle): the imagery is licensed third-party aerial imagery, and in this style the source points directly at the imagery provider's CDN so tiles come off the provider's own global edge. The source therefore carries the provider's credit —Imagery © Esri, Maxar, Earthstar Geographics— in itsattributionfield, in addition to© Navvo. Both must be displayed. The Navvo renderer's attribution control does this automatically from the style document; only build a custom attribution surface if you reproduce both strings. - Keep the renderer's compact attribution control visible — the Navvo SDKs show it by default.
GET /map/configreturns anattributionobject for custom attribution UIs — but note itssatellitevalue is© Navvo, not the imagery credit. A custom attribution surface must read the imagery credit from thesatellitesource's ownattributionfield in the style document, or it will omit a credit that is contractually required.
What the base map shows
The base map is geography, not a business directory: streets, buildings, land use, water, parks, and administrative place names. It carries no shops, restaurants, clinics, hotels, offices, banks or transit stops.
This is enforced in the tile data, not in the style. The upstream poi layer is removed from
every vector tile before it is served, so it is absent no matter which style renders it — ours,
one you wrote yourself, or a stock third-party style you point at our tiles. A style that
references source-layer: "poi" will simply draw nothing.
The only places Navvo shows are the ones in Navvo's own catalogue, and they are never painted onto the base map by default. Ask for them and they appear:
| You want | Call |
|---|---|
| Places matching a query | GET /search |
| Places near a point | GET /places?near=lat,lng |
| Places for a map viewport, ranked for the zoom | GET /map/poi |
Render the results as your own markers on top of the map. Nothing appears that you did not ask for, which also means a screenshot of the base map is stable: it does not change because somebody edited an upstream survey.
Tile sources
These endpoints back the styles above. The renderer requests them for you when it loads a style — you normally don't call them by hand. They're listed for completeness and for advanced/custom renderers.
| Endpoint | Returns |
|---|---|
GET /tiles/vector/navvo/planet/{z}/{x}/{y}.pbf | One vector tile (protobuf), application/x-protobuf. The path segment after navvo is typically planet; a .pbf extension on {y} is accepted. Cached public, max-age=86400. |
GET /tiles/tilejson/navvo | The vector tile catalog (TileJSON) the vector styles reference as their source url — tile template, zoom range, and vector layers. |
GET /tiles/raster/{source}/{z}/{x}/{y}.png | One raster tile. source ∈ standard, dark, satellite, navvo-natural-earth. Content type is decided by the source, not the extension: standard/dark → image/png; satellite → image/jpeg whatever extension you use; navvo-natural-earth → image/png, or image/webp if you request the .webp extension; native to zoom 6, and requests above it return 400 (roughly 70–95% smaller depending on zoom — this is the variant the live styles use). terrain is also routed here but is not currently available (returns 503 Terrain tiles are not configured). |
GET /tiles/glyphs/navvo/{fontstack}/{range}.pbf | Font glyph ranges (.pbf) referenced by the style's glyphs. |
GET /tiles/sprites/navvo/sprite | The sprite atlas base URL; the renderer appends .json (index), .png, and @2x.png (images). |
standard/dark return a neutral placeholder tile, not a rendering of the map — they are a flat background with generic decorative water/land/grid strokes, deliberately drawn without a road graph; use the vector styles for real cartography. satellite relays licensed third-party aerial imagery through Navvo (image/jpeg); the imagery credit still applies. navvo-natural-earth is the Navvo-hosted low-zoom shaded-relief world backdrop (add .webp for the compact variant). The vector, glyph, sprite, DEM and natural-earth resources are all served by Navvo; the satellite style is the one place where the browser talks to the imagery provider directly.You can also wire a raster source directly:
map.addSource("nav-sat", {
type: "raster",
tiles: ["https://navvo.io/api/v1/tiles/raster/satellite/{z}/{x}/{y}.png"],
tileSize: 256,
maxzoom: 19,
attribution: "© Navvo · Imagery © Esri, Maxar, Earthstar Geographics",
});
This wires the Navvo-relayed imagery path. The default /tiles/style?style=satellite instead points the source straight at the provider CDN for lower latency — either way, the imagery credit is required.
maxzoom: 19 on the satellite source. The satellite imagery is native to zoom 19; requests above it return 404. With maxzoom declared, the renderer overzooms real z19 pixels (sharp, instant) instead of firing requests that cannot succeed. The /tiles/style?style=satellite document already declares this for you — it only matters when you wire the raster source by hand.GET /tiles/layers
A small discovery catalog of available logical layers, style URLs, and raster tile templates.
{
"layers": ["administrative", "water", "buildings", "roads", "poi", "places"],
"styles": {
"standard": "/api/v1/tiles/style?style=standard",
"dark": "/api/v1/tiles/style?style=dark",
"satellite": "/api/v1/tiles/style?style=satellite",
"terrain": "/api/v1/tiles/style?style=terrain"
},
"tileProxy": {
"standardRaster": "/api/v1/tiles/raster/standard/{z}/{x}/{y}.png",
"darkRaster": "/api/v1/tiles/raster/dark/{z}/{x}/{y}.png",
"satelliteRaster": "/api/v1/tiles/raster/satellite/{z}/{x}/{y}.png",
"terrainRaster": "/api/v1/tiles/raster/terrain/{z}/{x}/{y}.png"
},
"timeMachine": {
"template": "/api/v1/tiles/gibs/{layer}/{z}/{x}/{y}?date={date}",
"defaultDate": "2026-07-25",
"layers": [
{ "key": "truecolor", "label": "True color (morning)", "maxZoom": 9 },
{ "key": "truecolor-aqua", "label": "True color (afternoon)", "maxZoom": 9 },
{ "key": "truecolor-viirs", "label": "True color (hi-res)", "maxZoom": 9 },
{ "key": "snow", "label": "Snow cover", "maxZoom": 8 },
{ "key": "aerosol", "label": "Aerosol / dust", "maxZoom": 6 }
]
}
}
terrainRaster is advertised in tileProxy but currently returns 503 Terrain tiles are not configured — don't wire it.
GET /tiles/cache/status
A read-only snapshot of Navvo's server-side tile cache — useful when you are diagnosing tile latency.
curl -s https://navvo.io/api/v1/tiles/cache/status
Unlike the rest of this page, this endpoint needs no API key.
strategy— the cache tiers in use.memory— the in-process tier:entries,bytes,maxBytes,ttlSeconds.disk— the durable tier:enabled,maxBytes,ttlSeconds.inflight— requests currently being fetched upstream and coalesced.metrics—memoryHits,diskHits,misses,inflightJoins,upstreamErrors.warming— the current prewarm run.policies— the per-source caching policy each tile class resolves to.
Informational only — nothing here changes how you request tiles.
Satellite Time-Machine (dated imagery)
Dated, multi-layer satellite imagery, proxied and brand-scrubbed. Request any registered layer at any date.
GET /tiles/gibs/{layer}/{z}/{x}/{y}?date=YYYY-MM-DD
| Layer | Native zoom | Format |
|---|---|---|
truecolor | 9 | JPEG |
truecolor-aqua | 9 | JPEG |
truecolor-viirs | 9 | JPEG |
snow | 8 | PNG |
aerosol (dust/air-quality) | 6 | PNG |
Requests deeper than a layer's native zoom are clamped server-side — the parent tile at the native level is returned (still 200) and the renderer overzooms it, so you never get a 404 for going too deep. Omitting date uses roughly two days ago; GET /tiles/layers → timeMachine.defaultDate is authoritative, and timeMachine.layers is the live registry of keys, labels and max zooms.
Terrain elevation (DEM)
Navvo-hosted elevation tiles (raster-dem) — the source behind 3D terrain (/tiles/style?style=3d&terrain=1) and hillshading. Coverage is Jordan; tiles outside the coverage bounds return 404 (treat that as "flat", not an error).
GET /terrain/tilejson
The DEM tileset descriptor (TileJSON): tile template, zoom range, bounds, and the elevation encoding.
curl -s "https://navvo.io/api/v1/terrain/tilejson" -H "x-api-key: $NAVVO_API_KEY"
{
"tilejson": "2.2.0", "name": "Navvo Jordan terrain", "scheme": "xyz",
"type": "raster-dem", "format": "png",
"encoding": "custom", "redFactor": 6553.6, "greenFactor": 25.6, "blueFactor": 0.1, "baseShift": -10000,
"attribution": "© Navvo",
"minzoom": 0, "maxzoom": 14, "bounds": [34.88, 29.12, 39.32, 33.38],
"tiles": ["/api/v1/terrain/tiles/{z}/{x}/{y}.png"],
"metadata": { "license": "ODbL", "generatedAt": "…", "tileCount": 61968 }
}
The DEM uses a custom encoding. Decode each tile pixel to metres with:
elevation_m = -10000 + R·6553.6 + G·25.6 + B·0.1
i.e. elevation = baseShift + R·redFactor + G·greenFactor + B·blueFactor. The Navvo Maps renderer applies these factors for you (see the note below); you only decode by hand for custom native pipelines.
GET /terrain/tiles/{z}/{x}/{y}.png
One elevation tile (PNG, RGB-encoded elevation). Cached public, max-age=604800, immutable. Out-of-bounds or unbuilt tiles → 404.
GET /tiles/style?style=3d&terrain=1 returns a style whose navvo-terrain-dem source already carries the exact decode parameters — the custom-encoding factors (redFactor, greenFactor, blueFactor, baseShift, i.e. elevation = baseShift + R·redFactor + G·greenFactor + B·blueFactor) — plus a tuned terrain.exaggeration. Use the style and the renderer decodes elevation automatically.Static map images
GET /tiles/static renders a non-interactive map image — for emails, receipts, chat previews, and social-share cards. No renderer needed; put the URL straight into an <img> or an og:image. It returns a PNG by default.
Query parameters
lat,lng — the map center (note: latitude first).13.WxH in pixels, each side 64–1280. Defaults to 600x400.lat,lng;lat,lng;…. Each renders as a Navvo pin.standard (default), dark, satellite, or terrain.<img>, native image views, and social crawlers). svg returns the legacy vector image (crisp at any scale, but browser-DOM only, and its markers are remote <image href> refs).curl -s "https://navvo.io/api/v1/tiles/static?center=31.9539,35.9106&zoom=14&size=600x400&markers=31.9539,35.9106&style=standard" \
-H "x-api-key: $NAVVO_API_KEY" -o preview.png
Responses are cached (Cache-Control: public, max-age=3600) and carry the © Navvo attribution strip baked into the image. Scope: tiles.