N-Ways
Developer docsMaps

Maps

Hosted styles, vector tiles, fonts and static map images.

On this page
Note:

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

NameInTypeDescription
stylepathstringRequired. One of: streets-light, streets-dark.
langquerystringOne of: en, fr, pt. Default: en.
formatquerystringOne of: mvt, pmtiles. Default: mvt.
cURL
curl "https://nways.ng/maps/v1/styles/streets-light.json" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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)

200 OK
{}

Errors

  • default Error

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
curl "https://nways.ng/maps/v1/tiles/countries.json" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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

200 OK
[
  {
    "name": "togo",
    "country": "TG",
    "detail": "cities",
    "bbox": [
      0
    ],
    "files": {
      "base": "togo.pmtiles",
      "detail": "togo-detail.pmtiles",
      "transit": "togo-transit.pmtiles"
    },
    "outline": [
      [
        "string"
      ]
    ]
  }
]

Errors

  • default Error

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

NameInTypeDescription
tilesetpathstringRequired. A file name from /tiles/countries.json, without .pmtiles
RangeheaderstringRequired.
cURL
curl "https://nways.ng/maps/v1/tiles/COUNTRY.pmtiles" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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

  • default Error

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

NameInTypeDescription
tilesetpathstringRequired. One of: base, detail, transit.
zpathintegerRequired. ≥ 0, ≤ 16.
xpathintegerRequired. ≥ 0.
ypathintegerRequired. ≥ 0.
cURL
curl "https://nways.ng/maps/v1/tiles/base/0/0/0.mvt" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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

  • default Error

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

NameInTypeDescription
stackpathstringRequired.
rangepathstringRequired.
cURL
curl "https://nways.ng/maps/v1/fonts/Inter-Medium/0-255.pbf" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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

  • default Error

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

NameInTypeDescription
centerquerystringlat,lng
zoomquerynumber≥ 0, ≤ 20.
sizequerystringWIDTHxHEIGHT, 32–1280 px each Default: 640x400.
scalequeryintegerOne of: 1, 2. Default: 1.
themequerystringOne of: light, dark. Default: light.
formatquerystringOne of: png, jpg. Default: png.
markersquerystring[]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.
pathquerystring[]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.
signaturequerystring
cURL
curl "https://nways.ng/maps/v1/staticmap" \
  -H "X-NWays-Api-Key: YOUR_API_KEY"
JavaScript
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()
Python
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

  • default Error