Traffic feed and offline packs
Live road speeds for your systems, and map packs your apps download for use without a network.
On this page
Send your key as key=YOUR_API_KEY on the address, or in the X-NWays-Api-Key header. API keys
Base address: https://nways.ng/maps/v1/fleet
Road speeds in a box (product traffic_feed; enterprise)
GET https://nways.ng/maps/v1/fleet/traffic-feed
Aggregated speeds per road and direction from N-Ways' self-learning traffic, only where enough distinct devices contributed: live readings (last 30 minutes) need 2, typical speeds (by day type and 15-minute slot) need 3. Never a trace, a device count or a session. Geometry is the OSM way (GeoJSON [lng, lat]); direction is along (forward) or against (backward) its drawing. level: 0 free, 1 slow, 2 heavy, 3 standstill, against the road's free-flow speed.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
bbox | query | string | Required. minLng,minLat,maxLng,maxLat; at most 2° across. |
kind | query | string | One of: live, typical. Default: live. |
at | query | string (date-time) | kind=typical: the time of week (local day type and 15-minute slot); default now. |
mode | query | string | One of: car, motorcycle. Default: car. |
format | query | string | ndjson: a FeedInfo line, then one Feature per line (application/x-ndjson). One of: geojson, ndjson. Default: geojson. |
curl "https://nways.ng/maps/v1/fleet/traffic-feed?bbox=3.30%2C6.42%2C3.45%2C6.55" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/fleet/traffic-feed?bbox=3.30%2C6.42%2C3.45%2C6.55', {
headers: { 'X-NWays-Api-Key': process.env.NWAYS_API_KEY },
})
const data = await res.json()import os
import requests
res = requests.get(
"https://nways.ng/maps/v1/fleet/traffic-feed?bbox=3.30%2C6.42%2C3.45%2C6.55",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
Feed
| Field | Type | Description |
|---|---|---|
type | any | Required. |
properties | object | Required. |
properties.kind | string | One of: live, typical. |
properties.mode | string | One of: car, motorcycle. |
properties.bbox | number[] | At least 4 items, at most 4 items. |
properties.at | string (date-time) | |
properties.generatedAt | string (date-time) | |
properties.minDevices | integer | The k-anonymity threshold applied (live 2, typical 3). |
properties.attribution | string | |
features | object[] | Required. |
features[].type | any | Required. |
features[].geometry | object | Required. GeoJSON LineString |
features[].properties | object | Required. |
features[].properties.wayId | integer | Required. OpenStreetMap way id. |
features[].properties.direction | string | Required. One of: forward, backward. |
features[].properties.speedKmh | number | Required. |
features[].properties.freeFlowKmh | number | Required. |
features[].properties.level | integer | Required. ≥ 0, ≤ 3. |
features[].properties.source | string | Required. One of: live, typical. |
features[].properties.updatedAt | string (date-time) | Live only, to the minute. |
{
"type": "string",
"properties": {
"kind": "live",
"mode": "car",
"bbox": [
0
],
"at": "2026-10-15T09:00:00+01:00",
"generatedAt": "2026-10-15T09:00:00+01:00",
"minDevices": 0,
"attribution": "string"
},
"features": [
{
"type": "string",
"geometry": {},
"properties": {
"wayId": 0,
"direction": "forward",
"speedKmh": 0,
"freeFlowKmh": 0,
"level": 0,
"source": "live",
"updatedAt": "2026-10-15T09:00:00+01:00"
}
}
]
}Errors
defaultError
Regions offline packs are made for
GET https://nways.ng/maps/v1/fleet/offline/regions
curl "https://nways.ng/maps/v1/fleet/offline/regions" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/fleet/offline/regions', {
headers: { 'X-NWays-Api-Key': process.env.NWAYS_API_KEY },
})
const data = await res.json()import os
import requests
res = requests.get(
"https://nways.ng/maps/v1/fleet/offline/regions",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
Regions
| Field | Type | Description |
|---|---|---|
regions | Region[] | Required. |
regions[].id | string | Required. |
regions[].name | string | Required. |
regions[].country | string | Required. |
regions[].bbox | number[] | Required. At least 4 items, at most 4 items. |
maxzoom | integer | Required. |
custom | object | Required. |
custom.maxDegrees | number | |
custom.step | number |
{
"regions": [
{
"id": "lagos",
"name": "string",
"country": "NG",
"bbox": [
0
]
}
],
"maxzoom": 15,
"custom": {
"maxDegrees": 0.6,
"step": 0.05
}
}Errors
defaultError
A region's pack manifest (202 while it's built; ask again after Retry-After)
GET https://nways.ng/maps/v1/fleet/offline/packs/{region}
A pack is the region's map (map.pmtiles, an extract of the archive the Maps SDK draws; open it with MapLibre Native's pmtiles:// support) and its routing graph tiles (routing.tar, Valhalla level 0–2 tiles with the engine's own paths) for on-device routing. Built once per map and graph version; version changes when either does.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
region | path | string | Required. A region id, or custom with bbox. |
bbox | query | string | region=custom: minLng,minLat,maxLng,maxLat, snapped outwards to 0.05°, at most 0.6° across. |
maxzoom | query | integer | Default: 15. ≥ 8, ≤ 15. |
curl "https://nways.ng/maps/v1/fleet/offline/packs/lagos" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/fleet/offline/packs/lagos', {
headers: { 'X-NWays-Api-Key': process.env.NWAYS_API_KEY },
})
const data = await res.json()import os
import requests
res = requests.get(
"https://nways.ng/maps/v1/fleet/offline/packs/lagos",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
Ready
| Field | Type | Description |
|---|---|---|
region | Region | Required. |
region.id | string | Required. |
region.name | string | Required. |
region.country | string | Required. |
region.bbox | number[] | Required. At least 4 items, at most 4 items. |
maxzoom | integer | Required. |
version | string | Required. |
status | string | Required. One of: building, ready. |
builtAt | string (date-time) | |
files | object[] | Required. |
files[].name | string | Required. One of: map.pmtiles, routing.tar. |
files[].bytes | integer | Required. |
files[].sha256 | string | Required. |
files[].url | string | Required. Path to download (add your key). |
notes | string[] |
{
"region": {
"id": "lagos",
"name": "string",
"country": "NG",
"bbox": [
0
]
},
"maxzoom": 0,
"version": "string",
"status": "building",
"builtAt": "2026-10-15T09:00:00+01:00",
"files": [
{
"name": "map.pmtiles",
"bytes": 0,
"sha256": "string",
"url": "string"
}
],
"notes": [
"string"
]
}Errors
defaultError
Download a pack file (Range requests supported; ETag = its hash)
GET https://nways.ng/maps/v1/fleet/offline/packs/{region}/{file}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
region | path | string | Required. A region id, or custom with bbox. |
file | path | string | Required. One of: map.pmtiles, routing.tar. |
bbox | query | string | region=custom: minLng,minLat,maxLng,maxLat, snapped outwards to 0.05°, at most 0.6° across. |
maxzoom | query | integer | Default: 15. ≥ 8, ≤ 15. |
curl "https://nways.ng/maps/v1/fleet/offline/packs/lagos/map.pmtiles" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/fleet/offline/packs/lagos/map.pmtiles', {
headers: { 'X-NWays-Api-Key': process.env.NWAYS_API_KEY },
})
const data = await res.json()import os
import requests
res = requests.get(
"https://nways.ng/maps/v1/fleet/offline/packs/lagos/map.pmtiles",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
The file
Errors
409ErrordefaultError