API keys and security
Every request carries an API key. Restrict each key to the sites, apps or servers that use it and to the APIs it needs, so a copied key is useless to anyone else.
On this page
Getting keys. Sign up in the partner console with Google, Apple or email and your first key is made at once; you create more yourself, with their restrictions; each key is shown once, when you create it. Without a key, the APIs, tiles and fonts refuse requests from websites other than N-Ways’ own (403).
Projects and keys
A project holds your keys, the APIs they may call, their quotas and their usage. Use one project per app and environment (for example Rider app and Rider app, test), so a test script never uses up production’s quota.
A project can have several keys. Give each website, app and server its own key, so you can restrict it tightly and replace it without touching the others.
Sending your key
Add key=YOUR_API_KEY to the address of every request: web service calls, tiles and fonts. The Maps SDK does it for you.
GET /maps/v1/geocode?q=Wuse+2+Abuja&key=YOUR_API_KEY HTTP/1.1
Host: nways.ngFrom a server you may send it in a header instead, so it stays out of your logs of addresses:
GET /maps/v1/geocode?q=Wuse+2+Abuja HTTP/1.1
Host: nways.ng
X-NWays-Api-Key: YOUR_API_KEYFrom a web page, either works: with the header, the browser first asks permission (a CORS preflight), which N-Ways grants; the request itself is then checked. Answers to your website carry Access-Control-Allow-Origin for it, so your page can read them, and refusals too, so your code can read the reason.
N-Ways answers other websites’ pages only when they send a key the website may use. Without one, map data and the APIs are kept for the N-Ways apps.
Application restrictions
An application restriction says where a key may be used. Each key has one kind:
| Kind | Use it for | How N-Ways checks it |
|---|---|---|
| Websites | Maps and calls from a web page | The page’s address the browser sends (the Referer or Origin header) |
| Android apps | Calls from your Android app | The app’s package name and the SHA-1 fingerprint of its signing certificate, in the X-Android-Package and X-Android-Cert headers (the Android SDK sends them for you) |
| iOS apps | Calls from your iPhone app | The app’s bundle ID, in the X-Ios-Bundle-Identifier header (the iOS SDK sends it for you) |
| IP addresses | Calls from your servers | The address the request comes from |
| None | Trying things out only | Nothing. Don’t ship a key without a restriction. |
Website addresses
List each site the key may be used on. A * stands for any subdomain at the start, or anything at the end of the path:
| Entry | Allows | Doesn’t allow |
|---|---|---|
https://example.com/* | Every page on example.com | www.example.com, http://example.com |
https://*.example.com/* | www.example.com, shop.example.com | example.com itself: add it too |
https://example.com/track/* | Pages under /track/ | Anything else on the site |
http://localhost:5173/* | Your machine, while developing | Keep it on a development key only |
Browsers often send only the site’s origin, not the full page address. If a path-based entry doesn’t match, allow the whole site.
Android and iOS apps
An Android entry is the package name and the certificate’s SHA-1, separated by a semicolon: com.example.rider;DA:39:A3:EE:…:07:09 (colons optional). Use the fingerprint of the certificate the store signs your app with. An iOS entry is the bundle ID: com.example.rider.
IP addresses
List your servers’ public addresses, one per line: single addresses (203.0.113.7, 2001:db8::7) or ranges (198.51.100.0/24). Behind a NAT gateway or a cloud load balancer, list the gateway’s outgoing address.
API restrictions
An API restriction says what a key may call. Pick only what that app uses:
| API | Covers |
|---|---|
| Maps (tiles) | Hosted styles (/maps/v1/styles/…, one map load each), tiles and fonts (/maps/v1/tiles/…, /maps/v1/fonts/…, and the earlier /tiles/…, /fonts/…): what the Maps SDKs read |
| Static maps | /maps/v1/staticmap |
| Geocoding | /maps/v1/geocode, /reverse, /postcodes/…, /ghanapost/…, /pluscodes/… (and the earlier /v1/geocode, /v1/reverse, /v1/postcodes/{code}, /v1/ghanapost/{code}) |
| Autocomplete | /maps/v1/autocomplete |
| Address validation | POST /maps/v1/addresses/validate |
| Places | /maps/v1/places/… (and the earlier /v1/search, /v1/places, /v1/places/{id}, POST /v1/places/along) |
| Routes | POST /maps/v1/routes/compute (and the earlier POST /v1/routes, POST /v1/routes/check) |
| Route matrix | POST /maps/v1/routes/matrix |
| Route optimisation | POST /maps/v1/routes/optimize |
| Fares | /maps/v1/fares/estimate (and the earlier /v1/fares/estimate) |
| Traffic | /maps/v1/traffic (and the earlier /v1/traffic) |
| Fleet | /maps/v1/fleet/… except the traffic feed: vehicles, positions, deliveries, tracking links, webhooks, offline packs |
| Traffic feed | /maps/v1/fleet/traffic-feed |
| Photos | Place photos (/photos/…) |
A key never lets anyone report, add or change anything on the map, and never reaches accounts. Only Fleet changes data, and only your own (your vehicles, deliveries and webhooks).
A call to an API the key isn’t allowed answers 403 with the reason API_KEY_SERVICE_BLOCKED. Key errors
Rotating a key
Replace a key when it may have leaked, when someone who knew it leaves, or once a year:
- Ask us to regenerate the key, or to create a new one with the same restrictions. A regenerated key can keep its old value working for 24 hours, while you release the new one.
- Put the new key in your site, app or server, and release it.
- Watch the old key’s usage fall in the console. Apps on phones update slowly: give it days, not minutes.
- Disable the old key. Requests with it answer
403 API_KEY_PAUSEDwithin seconds, saying the key is paused. If something breaks, enable it again while you fix it. - Delete the old key once its usage has stayed at zero.
If a key leaks
Restrict it at once (a website key to your sites, a server key to your IP addresses), then rotate it as above. If you can’t restrict it, disable it: your app stops working with it until you release the new key. Tell us at hello@nways.ng and we’ll help check its usage.
Best practices
- One key per website, app and server, each with an application restriction and only the APIs it needs.
- Keep server keys on servers. Never put a key restricted by IP address in a web page or app, and never commit a key to your code repository: read it from an environment variable or your secret store.
- Call web services from your server when you can. A web page that needs routes can ask your server, which calls N-Ways with a server key.
- Set your own caps on each key, so a bug or abuse can’t use up your quota. Quotas and limits
- Keep test and production apart, in separate projects.
- Remove what you don’t use: unused keys, and APIs a key no longer needs.