Routes
Directions the way people really travel here: by car, okada, keke, danfo, on foot, by train or by boat, with live traffic, tolls, okada and keke bans, borders, and what the ride should cost.
Base address: https://nways.ng/maps/v1. Routes, fares and traffic here; for many origins and destinations at once see the route matrix, and for a batch of stops route optimisation. Reference
Get a route
POST /maps/v1/routes/compute with a JSON body.
curl -X POST "https://nways.ng/maps/v1/routes/compute" \
-H "X-NWays-Api-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"origin": {"lat": 6.6018, "lng": 3.3515}, "destination": {"postcode": "LA08A09DB09"}, "mode": "okada", "fares": true}'import { createClient } from '@nways/maps'
const nways = createClient({ key: process.env.NWAYS_API_KEY })
const { routes } = await nways.route({
origin: { lat: 9.0579, lng: 7.4951 },
intermediates: [{ lat: 9.0765, lng: 7.3986 }],
destination: { lat: 9.0034, lng: 7.2633 },
mode: 'drive',
avoid: ['tolls'],
})
console.log(Math.round(routes[0].durationS / 60), 'min')import os
import requests
res = requests.post(
"https://nways.ng/maps/v1/routes/compute",
headers={"X-NWays-Api-Key": os.environ["NWAYS_API_KEY"]},
json={"origin": {"lat": 5.6037, "lng": -0.187}, "destination": {"lat": 6.1319, "lng": 1.2228}, "mode": "drive", "lang": "fr"},
timeout=20,
)
res.raise_for_status()
best = res.json()["routes"][0]
print(round(best["durationS"] / 60), "min")Request body
| Field | Description |
|---|---|
origin, destination | Required. A { "lat", "lng" } point, a NIPOST { "postcode" } (the route ends at the building’s best entrance), a { "ghanaPost" } address or a { "plusCode" }. The origin may have a heading in degrees, so a moving vehicle doesn’t start with a U-turn. |
intermediates | Up to 25 stops on the way, in order, in the same forms. |
mode | drive (default), van, okada (a motorbike taxi: keeps to okada bans), motorbike (your own motorbike: commercial bans don’t apply), keke and danfo (keep to their bans), walk, bicycle, boat (passenger boats and jetties), train. |
alternatives | true for up to 2 more routes (without intermediates). |
routingPreference | traffic_unaware (default) or traffic_aware: live traffic and reported incidents. |
departAt | When the trip starts (RFC 3339): boats run in daylight, and traffic follows the hour. |
avoid | Any of tolls, highways, bad_roads (roads drivers reported as rough or flooded). |
tollVehicle | The toll tariff class: car, suv, bus, truck. |
access | Train and boat trips: how to reach and leave the station or jetty: walk, okada or drive. |
lastMile | Where the road stops short of the door: finish on foot (walk) or by okada. |
allowBans | IDs of reported, unconfirmed bans to ride through anyway. |
fares | true adds what the trip should cost to each route. |
lang | en (default) or fr, for instructions. |
?fields= keeps only some fields of each route, such as fields=distanceM,durationS,geometry.
Response
{
"routes": [
{
"distanceM": 1395,
"durationS": 228,
"staticDurationS": 228,
"trafficDelayS": 0,
"summary": "Admiralty Way and Awudu Ekpekha Boulevard",
"geometry": { "type": "LineString", "coordinates": [[3.472352, 6.4474], [3.472352, 6.447802], "…"] },
"legs": [{ "distanceM": 1395, "durationS": 228 }],
"steps": [
{ "maneuver": "depart_left", "instruction": "Drive north on Victoria Arobieke Street.", "distanceM": 44, "durationS": 6, "streetNames": ["Victoria Arobieke Street"], "startIndex": 0, "endIndex": 1 }
],
"country": "NG"
}
]
}| Field | Description |
|---|---|
routes | The best route first, then any alternatives. |
distanceM, durationS | Length in metres and time in seconds. |
staticDurationS, trafficDelayS | The time without live traffic, and what traffic and incidents add now (with traffic_aware). |
geometry | A GeoJSON LineString, ready for a map layer. |
steps | Turn-by-turn: instruction, distance, time, streetNames, and where each starts and ends in geometry; roundabout exits, traffic lights, and footbridges or zebra crossings on foot. |
legs | One per part between stops. |
segments | Trips that change how you travel: a train or boat, or an okada that walks past a ban area. |
vehicleRules | Okada, keke and danfo trips: the bans the route kept out of (avoided), rules that are advice only, a start or end inside a ban area (endBan), and where riders say they’re stopped. |
lastMile | Where to stop when the road ends before the door, and how to finish. |
access | A gated estate or compound at the destination. |
tolls, borderCrossings | Toll gates and what they cost in their currencies; border posts on trips between countries. |
congestion, roadCondition | Slow stretches; rough, flooded or damaged stretches drivers reported. |
fares | With fares: true: what the trip should cost (see Fares). |
warnings | Anything else worth telling the rider. |
Errors
| Status | Reason | Meaning |
|---|---|---|
| 400 | MODE_INVALID, WAYPOINT_INVALID, TOO_MANY_INTERMEDIATES… | A missing or wrong field. The message says which. |
| 404 | POSTCODE_NOT_FOUND, GHANAPOST_NOT_FOUND | A code N-Ways can’t place. |
| 422 | NO_ROUTE, NO_ROAD_ROUTE | No route: a point is too far from any road, or across water (try boat or walk). |
| 422 | OKADA_BANNED_ORIGIN, …_DESTINATION, …_STOP, …_ROUTE | An okada can’t do this trip; the same for MOTORBIKE_BANNED_…, KEKE_BANNED_… and DANFO_BANNED_…. |
| 422 | ROUTE_TOO_FAR | The places are too far apart for one route of this kind. |
| 503 | ROUTING_UNAVAILABLE | The routing engine is busy or restarting. Retry after a minute. |
Basic routes (car, van, walking and cycling without live traffic, up to 10 stops) and advanced ones (live traffic, okada, keke, danfo, motorbike, boat, train, more than 10 stops, or fares) are priced differently. Pricing
Fares
What a ride should cost, in the country’s money: taxi, shared taxi, okada, keke, danfo or bus, boat and ride-hailing, from what riders paid (basis: crowd) or published sources (basis: guide), with night, rush hour, rain and chartered rides.
GET /maps/v1/fares/estimate
| Parameter | Description |
|---|---|
from, to | Required. lat,lng each. |
mode | Comma-separated: taxi, shared_taxi, okada, keke, danfo, ridehail, boat. All if not given. |
distanceM, durationS | The route’s length and time, if you have them; better estimates. |
at | When the trip is (RFC 3339): night and rush hour cost more. |
charter, rain | true for a chartered (“drop”) ride, or in rain. |
lang | en or fr. |
curl "https://nways.ng/maps/v1/fares/estimate?from=6.4474,3.4720&to=6.5244,3.3792&mode=okada,taxi" \
-H "X-NWays-Api-Key: YOUR_API_KEY"The answer has the currency and one estimates entry per mode with low, typical and high prices (in the currency’s main unit), a written text such as ₦8,150–15,200, whether it’s perPerson, and its sources. Modes the law keeps off the trip are in notAllowed, with the rule and its source (okadas are banned in much of Lagos).
Live traffic
curl "https://nways.ng/maps/v1/traffic?bbox=3.30,6.40,3.50,6.60" -H "X-NWays-Api-Key: YOUR_API_KEY"Roads with live readings in a box (minLng,minLat,maxLng,maxLat, under 3° across), as GeoJSON lines with a congestion level, for drawing on a map. Readings come from N-Ways phones on the road, anonymously. Don’t cache it: it changes by the minute. For speeds per road and direction, for your own ETAs, see the traffic feed.
The earlier address
POST https://nways.ng/v1/routes (with from, to and stops) and /v1/fares/estimate keep working for partners who started with them for at least 12 months, but their answers follow the N-Ways app. Move to /maps/v1, whose answers only ever gain fields.