Startup Program credit keys
Startup Program credit pays only for your own products’ calls, made with credit keys that prove where they come from. Everything else is billed as usual.
On this page
For companies in the N-Ways Startup Program. The credit is for your own products only. Reselling it, sharing keys or proxying N-Ways for other companies breaks the Startup Credit Agreement: the credit ends at once and the company and its founders can be banned.
How the credit pays
A call is paid from your startup credit only when all of these hold. Otherwise it is billed as normal paid usage from your organisation’s own credit, and refused with 402 STARTUP_CREDIT_NOT_ELIGIBLE if there is none.
- A founder verified at least one product and accepted the agreement on startup.nways.ng.
- The call uses a credit key: an API key of your company bound to one of your verified products, or to your servers.
- The call proves where it comes from (below).
- The credit isn’t paused, and the caps aren’t reached.
Every answer to a company with startup credit says what happened in X-NWays-Credit: startup when the credit paid, or paid; why=<code> when it couldn’t.
Verify your products
| Product | How it’s proved | Checked |
|---|---|---|
| Website | A DNS TXT record _nways-verify.example.com holding nways-verify=<token>. Subdomains are covered. | Automatically, then every day. Three failed checks in a row and it lapses. |
| iOS app | Bundle ID, Apple team ID and App Store link. The public listing’s developer website is one of your verified domains, or the token is in its description. | Automatically; an app that isn’t public yet is checked by N-Ways by hand. |
| Android app | Package name, app signing certificate SHA-256 and Google Play link. The public listing links to one of your verified domains, or shows the token in its description. | Automatically; otherwise by N-Ways by hand. |
You may add or replace 2 products in any 12 months after accepting. Each one is verified again.
Browser keys
Bind a key restricted to websites to a verified website. Its calls use the credit when the page’s Origin (or Referer) is that domain or one of its subdomains. Nothing else to send: browsers add the header.
Mobile keys and app attestation
Bind a key restricted to iOS or Android apps to your verified app. Its calls use the credit when they carry X-NWays-Attestation, a session the app gets by proving it is your genuine app on a real device. The N-Ways SDKs do it in one call, and the session lasts 30 days:
NWaysMaps.configure(apiKey: "YOUR_IOS_CREDIT_KEY")
Task { try? await NWaysCredit.start() } // App Attest; then sent on every N-Ways requestNWaysMaps.init(this, "YOUR_ANDROID_CREDIT_KEY")
thread { runCatching { NWaysCredit.start(this) } } // hardware key attestation (Android 7+)Without the SDK, make the same calls yourself:
POST /maps/v1/credit/attest/challengewith the key: a challenge valid for 5 minutes.- iOS:
DCAppAttestService.attestKeywithclientDataHash = SHA-256("nways-credit|" + challenge + "|" + keyId). Android: generate an Android Keystore key withsetAttestationChallengeset to that SHA-256 (your own randomkeyId). POST /maps/v1/credit/attestwith{"platform", "challenge", "keyId", "attestation"}(iOS, base64) or{"platform", "challenge", "keyId", "chain"}(Android: the certificate chain, base64 DER, leaf first). The answer is{"token", "expiresAt"}: send the token asX-NWays-Attestation.
N-Ways checks iOS attestations against Apple’s App Attest root and your team and bundle ID, and Android ones against Google’s hardware attestation roots, your package and your signing certificate. Nothing is needed from your Apple or Google accounts. Emulators, simulators and rooted devices without hardware attestation can’t attest: their calls are billed as usual.
Server keys
Most products call N-Ways from their own servers. Bind a key restricted to IP addresses (or not restricted) to your servers, then register their public egress addresses on startup.nways.ng: up to 5 addresses or ranges, IPv4 no wider than /28 and IPv6 no wider than /56, and up to 4 changes in 30 days.
Each new address is verified by one call made from it, with a server credit key and the challenge shown when you added it (valid 48 hours):
curl -X POST https://api.nways.ng/maps/v1/credit/verify-ip \
-H "X-NWays-Api-Key: YOUR_SERVER_CREDIT_KEY" \
-H "Content-Type: application/json" \
-d '{"challenge": "nwip_…"}'Every server call that should use the credit names the end user it is for:
GET /maps/v1/places/search?query=pharmacy HTTP/1.1 Host: api.nways.ng X-NWays-Api-Key: YOUR_SERVER_CREDIT_KEY X-NWays-End-User: u_7f3a9c2d41e8
X-NWays-End-Useris an opaque ID from your own system: a salted hash or random ID, 8 to 128 letters, digits and. _ : = -. It is the same for one user and different for different users.- Never put personal data in it: no name, email address, phone number, ID or account number. Email addresses and phone numbers are refused.
X-NWays-End-User-Country(optional) is the user’s country, two letters.- Calls from an unregistered address, or without the header, are billed as usual.
Caps
- A month’s use of the credit: ₦100,000 to start, per calendar month (Lagos time).
- A day’s use per product (and for your servers together): ₦10,000.
- Route matrices and route optimisation: each up to 10% of the monthly cap a month.
Past a cap, calls are billed as usual until it resets. Your caps and what you used are on startup.nways.ng.
Monitoring
N-Ways watches how the credit is used: spikes against your own usage, websites that aren’t yours on browser keys, failed attestations, traffic far above what your application declared, machine-steady traffic, a few “end users” with huge volumes, several apps behind one server key, end users outside your country, and calls from unregistered addresses. When it looks like sharing or resale the credit is paused by itself (calls are billed as usual) and your billing contacts are told; N-Ways then reviews it.
Errors and the why codes
why | What it means | What to do |
|---|---|---|
key_not_bound | The key isn’t a credit key. | Bind it on startup.nways.ng. |
credit_not_active | The agreement isn’t accepted yet, or the credit ended. | Accept it on startup.nways.ng. |
credit_frozen | The credit is paused pending review. | Reply to N-Ways’ email. |
origin_not_verified | The page isn’t on a verified domain. | Verify the domain, or call from it. |
attestation_missing, attestation_invalid | No valid X-NWays-Attestation. | Call NWaysCredit.start() again. |
app_not_verified | Another app than the one the key is bound to. | Use the app’s own credit key. |
ip_not_registered | The server’s address isn’t registered and verified. | Register and verify it. |
end_user_missing, end_user_invalid | No opaque X-NWays-End-User. | Send your user’s opaque ID. |
key_restriction_changed | The key’s restriction no longer fits its binding. | Restore it, or bind the key again. |
monthly_cap, daily_cap, sku_cap | A cap is reached. | Wait for it to reset, or use paid credit. |
With no paid credit, these calls answer 402 STARTUP_CREDIT_NOT_ELIGIBLE with the code in metadata.why. See Errors.