Navvo
API Reference

Map Data & Risk

Map configuration, category styles, overlays, weather, and condition-aware route risk scoring.

Map Data & Risk

Everything that layers on top of the base map: the map configuration manifest, category marker styles, icon sprites, vector/GeoJSON overlays, weather, and route-risk scoring that fuses traffic, weather, incidents, logistics zones, and enforcement assets.

Scope required: tiles for configuration, overlays, and weather; routing for the route-risk/enforcement POST endpoints.

Coordinates are GeoJSON [lng, lat]; bbox is west,south,east,north. Heavy overlays support a bbox/zoom/limit filter and a tile-cover planner for bounded loading. Most endpoints degrade gracefully (empty FeatureCollection with hasData:false) rather than erroring on bad input.

GET /map/config

The full first-party map configuration manifest: base styles, overlays, categories, icons, weather, 3D, logistics zones, and a capabilities block describing public endpoints and performance limits. Fetch this once at startup to discover what's available and how to load it.

Top-level keys: layers, baseStyles, overlays, categories, icons, iconSpriteUrl, iconSpriteManifestUrl, categoryStyleManifest, threeD, logisticsZones, capabilities.

{
  "baseStyles": [ { "key": "standard", "name": "Navvo", "kind": "base", "endpoint": "/api/v1/tiles/style?style=standard" } ],
  "overlays": [ { "key": "traffic", "kind": "overlay", "layerType": "traffic", "tileUrl": "/api/v1/traffic/lines/tiles/{z}/{x}/{y}" } ],
  "iconSpriteUrl": "/api/v1/map/icons/sprite.svg",
  "capabilities": {
    "publicEndpoints": { "config": "/api/v1/map/config", "routeRisk": "/api/v1/map/route-risk" },
    "performance": { "defaultTileCoverCap": 64, "maxTileCoverCap": 256, "tileAddressedOverlays": true },
    "vectorOverlays": { "enabled": true, "format": "mvt" }
  }
}

GET /map/layers

A flat catalog of all configured layers: { items, baseStyles, overlays, total, requiredOverlays }. requiredOverlays lists the overlay layer types Navvo expects (e.g. traffic, transit, incidents, weather, logistics_zones).


GET /map/category-styles

Renderer-ready styling for place categories — marker colors, pin styles, icons, multilingual names, and aliases. Use it to draw category-colored markers that match Navvo's own map.

{
  "version": 1,
  "iconSpriteUrl": "/api/v1/map/icons/sprite.svg",
  "categories": [
    {
      "slug": "restaurants",
      "name": { "en": "Restaurants", "ar": "مطاعم" },
      "color": "#F97316",
      "pinStyle": "teardrop",
      "zoomRange": { "min": 11, "max": 22 },
      "icon": { "name": "utensils", "href": "/api/v1/map/icons/sprite.svg#navvo-icon-utensils" }
    }
  ]
}

GET /map/icons/sprite.svg & sprite.json

sprite.svg returns an SVG symbol sprite (image/svg+xml) of all active icons (<symbol id="navvo-icon-…">). sprite.json returns the manifest describing each icon (name, id, href, size).

GET /map/readiness

A self-audit of the map surface — a list of boolean checks plus a summary (counts of base styles, overlays, categories, icons). Useful for diagnostics.


Overlays

Generic overlays serve stored map features as GeoJSON, vector tiles, or raster. Known layer types include traffic, transit, biking, terrain, incidents, speed_cameras, traffic_cameras, traffic_lights, weather, and logistics_zones.

GET /map/overlays/{layerType}

GeoJSON FeatureCollection for one overlay. Accepts bbox, limit, zoom.

{
  "type": "FeatureCollection",
  "features": [
    { "type": "Feature", "geometry": { "type": "Point", "coordinates": [35.91, 31.95] },
      "properties": { "id": 12, "name": "Amman central speed camera", "layerType": "speed_cameras", "color": "#B91C1C" } }
  ],
  "metadata": { "layerType": "speed_cameras", "name": "Speed cameras", "hasData": true }
}
biking (cycling network) and transit return live, viewport-driven network data (cached per area). For biking, each LineString/MultiLineString carries network (protected | shared | trail), surface, lit, oneway, and color. For transit, features carry kind (line | stop), mode (bus | metro | tram | rail), color, and (for lines) routeRef, lineName, network. Pass a bbox to scope the request.

Tiled overlay access

EndpointReturns
GET /map/overlays/{layerType}/tile-coverTile URLs covering a bbox (bbox, zoom, maxTiles).
GET /map/overlays/{layerType}/tiles/{z}/{x}/{y}One tile as GeoJSON.
GET /map/overlays/{layerType}/vector/{z}/{x}/{y}One tile as a binary vector tile (application/x-protobuf, layer navvo).

GET /map/logistics-zones.geojson

Logistics / SLA zone polygons as GeoJSON. Each feature carries zoneType, riskScore, costMultiplier, and routingPolicy — the same zones surfaced in /routing/plan results.


Weather

Weather overlays are stored polygons plus a live point lookup. typeprecipitation, temperature, clouds, storms, alerts; time-1h, now, +1h, +3h.

EndpointReturns
GET /map/weather/geojsonWeather polygons as GeoJSON (filters: type, time, bbox, limit, zoom).
GET /map/weather/geojson/tiles/{z}/{x}/{y}Weather GeoJSON for one tile.
GET /map/weather/vector/{z}/{x}/{y}Weather as a binary MVT (layer navvo_weather).
GET /map/weather/tiles/{z}/{x}/{y}A rendered SVG raster weather tile (image/svg+xml).
GET /map/weather/tile-coverTile URLs covering a bbox.
GET /map/weather-riskAggregate weather-risk preview (score, severity, warnings).

GET /map/weather/point

Current point weather (from Navvo's weather service).

lat
number required
Latitude.
lng
number required
Longitude (lon also accepted).
units
string
metric (default) or imperial.
{
  "ok": true, "lat": 31.95, "lon": 35.91, "city": "Amman",
  "temperature": 28, "unit": "C", "feelsLike": 30, "humidity": 35,
  "windSpeed": 12, "windUnit": "km/h", "visibility": 16, "visibilityUnit": "km",
  "condition": "Clear sky",
  "aqi": 40, "aqiCategory": "Good", "pm25": 9, "pm10": 16, "dust": 1,
  "source": "Navvo weather point service"
}

The response also carries live air quality: aqi (US AQI), aqiCategory (GoodHazardous), pm25/pm10 (µg/m³), and dust (µg/m³, desert dust concentration). These are null if the air-quality source is briefly unavailable. This endpoint returns 400 on invalid coordinates (the only one in this module that does); upstream failures return 200 with ok:false.

GET /map/weather/forecast

Hourly weather forecast for a point — the next N hours (default 24, max 72).

lat
number required
Latitude.
lng
number required
Longitude (lon also accepted).
hours
number
How many hours to return (default 24, max 72).
units
string
metric (default) or imperial.
{
  "ok": true, "lat": 31.95, "lon": 35.91, "city": "Amman",
  "units": "metric", "unit": "C", "windUnit": "km/h", "hours": 6,
  "forecast": [
    { "time": "2026-06-27T19:00:00.000Z", "temperature": 22.8, "condition": "Clear", "precipitationMm": 0, "windSpeed": 9, "humidity": 38 },
    { "time": "2026-06-27T20:00:00.000Z", "temperature": 22, "condition": "Clear", "precipitationMm": 0, "windSpeed": 8, "humidity": 41 }
  ]
}
FieldTypeNotes
forecast[].timestringISO hour
forecast[].temperaturenumberin unit (C/F)
forecast[].conditionstringhuman label
forecast[].precipitationMmnumber | nullrain in the hour
forecast[].windSpeednumberin windUnit

400 on invalid coordinates; upstream failures return 200 with ok:false and an empty forecast.

GET /map/weather/alerts

Derived weather warnings for a point — scans the next N hours of forecast and returns alerts for threshold breaches: heat (≥37 °C, especially relevant for MENA), cold/freezing (≤1 °C), heavy rain (≥4 mm/h), and strong wind (≥40 km/h). Each alert carries a severity (moderate/high/severe), a peak value, and the hour it occurs.

?lat=&lng=&hours= (default 24, max 72).

{
  "ok": true, "provider": "navvo-weather", "lat": 24.63, "lon": 46.72, "city": "",
  "checkedHours": 48, "count": 1,
  "alerts": [
    { "type": "heat", "severity": "severe", "message": "High temperatures up to 43°C", "valueC": 43, "at": "2026-06-28T12:00:00.000Z" }
  ]
}

count: 0 (empty alerts) means no thresholds were breached in the window. 400 on invalid coordinates.

GET /map/weather/cities

Weather pins for the cities/towns inside a viewport — used to label current conditions on the map at city zoom. Returns a GeoJSON FeatureCollection of points; only meaningful at zoom ≥ 7 (lower zooms return an empty collection quickly), and the count is capped so the map stays readable.

bbox
string required
Viewport bounds west,south,east,north.
zoom
number required
Current map zoom (< 7 returns empty).
units
string
metric (default) or imperial.
limit
number
Max pins (auto-scaled by zoom; hard cap 24).
{
  "type": "FeatureCollection",
  "features": [
    { "type": "Feature", "geometry": { "type": "Point", "coordinates": [35.93, 31.95] },
      "properties": { "name": "Amman", "temperature": 30, "unit": "C", "condition": "Clear",
        "code": 0, "icon": "clear", "color": "#386BFF" } }
  ],
  "metadata": { "layerType": "weather_cities", "name": "Weather", "hasData": true }
}

icon is a neutral family — one of clear, cloud, rain, storm, snow, fog — and code is its numeric equivalent (05).

GET /map/airquality/cities

Air-quality pins (US AQI + dust) for the cities/towns inside a viewport — the AQI counterpart of /map/weather/cities, for labelling air quality on the map at city zoom. Returns a GeoJSON FeatureCollection of points; only meaningful at zoom ≥ 7, and the count is capped (hard cap 20). Values are cached ~15 min per cell.

bbox
string required
Viewport bounds west,south,east,north.
zoom
number required
Current map zoom (< 7 returns empty).
limit
number
Max pins (auto-scaled by zoom; hard cap 20).
{
  "type": "FeatureCollection",
  "features": [
    { "type": "Feature", "geometry": { "type": "Point", "coordinates": [35.92, 31.95] },
      "properties": { "name": "Amman", "aqi": 40, "aqiCategory": "Good",
        "pm25": 10, "pm10": 16, "dust": 1 } }
  ],
  "metadata": { "layerType": "air_quality_cities", "name": "Air quality", "hasData": true }
}

aqi is the US AQI; aqiCategory is its band (Good, Moderate, Unhealthy (sensitive), Unhealthy, Very unhealthy, Hazardous). pm25/pm10/dust are µg/m³. The same per-point values back the aqi/dust fields on /map/weather/point.


Route risk & enforcement

Score a route against live conditions across five layers — traffic, weather, incidents, logistics zones, and enforcement assets (cameras/signals) — using geometry intersection.

POST /map/route-risk

Scope: routing.

Request body

geometry
object | array required
The route geometry. Accepts a GeoJSON LineString/Feature/FeatureCollection, a raw array of [lng, lat] pairs, or any object with a coordinates field. (route is accepted as an alias.)
routeId
string
Echoed in the response. Defaults to preview.
timeOffset
string
-1h, now (default), +1h, or +3h — which weather snapshot to score against.
{
  "routeId": "trip-42",
  "timeOffset": "+1h",
  "geometry": { "type": "LineString", "coordinates": [[35.91,31.95],[35.93,31.97],[35.95,31.99]] }
}

Response (200)

{
  "ok": true,
  "routeId": "trip-42",
  "hasRouteGeometry": true,
  "timeOffset": "+1h",
  "scores": { "overall": 24, "traffic": 40, "weather": 10, "incidents": 0, "logistics": 32, "cameras": 16 },
  "severity": "low",
  "stack": [
    { "key": "traffic", "label": "Traffic speed", "score": 40, "severity": "medium", "detail": "Moderate congestion exposure on this route.", "count": 3 }
  ],
  "warnings": [
    { "type": "traffic", "severity": "high", "title": "Heavy traffic segment", "detail": "18 km/h average · 42 samples", "location": { "lng": 35.93, "lat": 31.97 } },
    { "type": "logistics", "severity": "medium", "title": "Amman core congestion SLA", "location": { "lng": 35.91, "lat": 31.97 } }
  ]
}
FieldDescription
scores0–100 per layer plus a weighted overall.
severitylow / medium / high from the overall score.
stack[]Per-layer breakdown (score, severity, detail, count, source).
warnings[]Specific hazards along the route, each with a location anchor { lng, lat }.
There's also a GET /map/route-risk (scope tiles) that takes the route via a coords query string of lng,lat pairs separated by ; — handy for quick previews without a request body.

POST /map/route-enforcement

Scope: routing. Returns just the enforcement checkpoints (speed cameras, traffic cameras, traffic lights) along the route. Same request body as route-risk.

{
  "ok": true,
  "routeId": "trip-42",
  "count": 2,
  "items": [
    { "id": "speed_camera-0", "type": "speed_camera", "title": "Amman central speed camera", "detail": "Speed camera on or near route · 60 km/h", "confidence": 0.84, "location": { "lng": 35.92, "lat": 31.96 } }
  ]
}
Copyright © 2026