Maps
Hosted styles, vector tiles, fonts and static map images.
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
A hosted map style (one map load)
GET https://nways.ng/maps/v1/styles/{style}.json
A MapLibre style for the N-Ways street map with the key on every N-Ways URL (tiles, fonts). Point MapLibre GL JS or MapLibre Native at it: style: 'https://nways.ng/maps/v1/styles/streets-light.json?key=nw_…'. Each read is one map load (SKU map_loads, product tiles). Tiles come one at a time (/tiles/base/{z}/{x}/{y}.mvt, every country, with bounds around all of them), or from each country's PMTiles archive with format=pmtiles (needs the pmtiles protocol, as the web SDK registers): then the style has one source per country (nways-ng, nways-gh, …) and each layer once per country (roads-ng, roads-gh, …). Reasons: STYLE_NOT_FOUND, LANG_INVALID, FORMAT_INVALID.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
style | path | string | Required. One of: streets-light, streets-dark. |
lang | query | string | One of: en, fr, pt. Default: en. |
format | query | string | One of: mvt, pmtiles. Default: mvt. |
curl "https://nways.ng/maps/v1/styles/streets-light.json" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/styles/streets-light.json', {
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/styles/streets-light.json",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
A MapLibre style (version 8)
{}Errors
defaultError
Every country's tile archives
GET https://nways.ng/maps/v1/tiles/countries.json
The countries N-Ways maps today, each with its ISO code, box (bbox: west, south, east, north), outline (GeoJSON MultiPolygon coordinates) and its PMTiles archives (files.base, files.detail, files.transit; a kind may be missing while a country is being built). Read a tile from the archive of the country whose outline holds the tile's centre, then any other whose box it touches. Only the archives listed here are served (any other name is TILESET_NOT_FOUND), so read the list again rather than keeping file names. Free with any Maps key (counted, never charged). TILES_UNAVAILABLE when the server has no map data.
curl "https://nways.ng/maps/v1/tiles/countries.json" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/tiles/countries.json', {
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/tiles/countries.json",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
The list
[
{
"name": "togo",
"country": "TG",
"detail": "cities",
"bbox": [
0
],
"files": {
"base": "togo.pmtiles",
"detail": "togo-detail.pmtiles",
"transit": "togo-transit.pmtiles"
},
"outline": [
[
"string"
]
]
}
]Errors
defaultError
Read a country's PMTiles archive (range requests)
GET https://nways.ng/maps/v1/tiles/{tileset}.pmtiles
One country's vector tiles as a PMTiles v3 archive: <country>.pmtiles (Protomaps basemap schema, zoom 0–15), <country>-detail.pmtiles (zoom 12–16) or <country>-transit.pmtiles (zoom 5–15), as listed in /tiles/countries.json, read in pieces with Range: bytes=a-b (at most 8 MB a read; the whole archive is never served). The key is checked on the first read of an archive session from a site (every archive) and counted as one tiles call; the next reads within 2 minutes ride on that check. Reasons: TILESET_NOT_FOUND, RANGE_REQUIRED, RANGE_TOO_LARGE, TILES_UNAVAILABLE.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
tileset | path | string | Required. A file name from /tiles/countries.json, without .pmtiles |
Range | header | string | Required. |
curl "https://nways.ng/maps/v1/tiles/COUNTRY.pmtiles" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/tiles/COUNTRY.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/tiles/COUNTRY.pmtiles",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
The bytes asked for
Errors
defaultError
One vector tile
GET https://nways.ng/maps/v1/tiles/{tileset}/{z}/{x}/{y}.mvt
A Mapbox Vector Tile (one tiles call) from the archive of the country it lies in, so every country is in every tileset: base (zoom 0–15), detail (12–16) or transit (5–15). Gzipped when the client accepts it. 204 where there's no tile (open sea). Beyond the top zoom, overzoom (the style's source says maxzoom: 15). Reasons: TILESET_NOT_FOUND, TILE_INVALID, TILE_NOT_FOUND, TILES_UNAVAILABLE.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
tileset | path | string | Required. One of: base, detail, transit. |
z | path | integer | Required. ≥ 0, ≤ 16. |
x | path | integer | Required. ≥ 0. |
y | path | integer | Required. ≥ 0. |
curl "https://nways.ng/maps/v1/tiles/base/0/0/0.mvt" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/tiles/base/0/0/0.mvt', {
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/tiles/base/0/0/0.mvt",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
A tile
Errors
defaultError
Font glyphs for map labels (free)
GET https://nways.ng/maps/v1/fonts/{stack}/{range}.pbf
Glyph ranges for the style's fonts (Inter-Regular, Inter-Medium, Inter-SemiBold, Inter-Bold, Inter-Italic). Counted, never charged. Reasons: FONT_RANGE_INVALID, FONT_NOT_FOUND.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
stack | path | string | Required. |
range | path | string | Required. |
curl "https://nways.ng/maps/v1/fonts/Inter-Medium/0-255.pbf" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/fonts/Inter-Medium/0-255.pbf', {
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/fonts/Inter-Medium/0-255.pbf",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
Glyphs
Errors
defaultError
A map image
GET https://nways.ng/maps/v1/staticmap
A PNG or JPEG of the map, drawn by N-Ways from its own tiles, with markers and lines. Give center and zoom, or only markers and paths to frame them. One static_maps call.
Signed URLs. Add signature= (last) to use a URL anywhere (an e-mail, an app with no Referer) whatever the key's application restriction: the base64url HMAC-SHA256 of the URL's path and query (from /maps/v1/staticmap?, without signature) with the key's signing secret (base64url; N-Ways gives it to you with the key). A changed URL or a wrong signature: 403 SIGNATURE_INVALID.
Reasons: SIZE_INVALID, SCALE_INVALID, THEME_INVALID, FORMAT_INVALID, MARKERS_INVALID, PATH_INVALID, CENTER_REQUIRED, CENTER_INVALID, ZOOM_INVALID, URL_TOO_LONG, SIGNATURE_INVALID.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
center | query | string | lat,lng |
zoom | query | number | ≥ 0, ≤ 20. |
size | query | string | WIDTHxHEIGHT, 32–1280 px each Default: 640x400. |
scale | query | integer | One of: 1, 2. Default: 1. |
theme | query | string | One of: light, dark. Default: light. |
format | query | string | One of: png, jpg. Default: png. |
markers | query | string[] | Repeatable: styles, then points, by |: color:red|label:A|size:small|6.45,3.47|6.46,3.48. Colours: red, green, blue, orange, yellow, purple, black, white, gray, or 0xRRGGBB[AA]. Sizes tiny, small, mid. At most 100 markers. |
path | query | string[] | Repeatable: color:0x1e6fe8cc|weight:5|fillcolor:0x…|6.45,3.47|6.46,3.48, or an encoded polyline (precision 5) last: weight:4|enc:_p~iF~ps|U…. At most 10 paths, 2,000 points each. |
signature | query | string |
curl "https://nways.ng/maps/v1/staticmap" \
-H "X-NWays-Api-Key: YOUR_API_KEY"const res = await fetch('https://nways.ng/maps/v1/staticmap', {
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/staticmap",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
timeout=10,
)
data = res.json()Response
The image
Errors
defaultError