FOR DEVELOPERS

One GET.
One answer.

Ask whether an NSID belongs to a currently enrolled student. Get status, institution, programme and level back inside 250ms — or a 409 carrying the link that asks the student for permission.

No approval gate, no KYB and no sales call to reach sandbox. Keys are visible the moment you verify your email address; business verification is only required before production traffic.
REQUEST
curl https://api.bona.ng/v1/verify/NS-TEST-0001-AAAM \
  -H "Authorization: Bearer bona_test_7f2a…c91d"
200 OK · 84ms
{
  "verified": true,
  "status": "active",
  "statusLabel": "Currently enrolled",
  "institution": "University of Lagos",
  "programme": "B.Eng Electrical & Electronic Engineering",
  "level": 400,
  "expectedCompletion": "2027-07-31",
  "requestId": "req_9f2c41a08b3d"
}

Three tiers. Ask for the least.

The tier is not a plan you sit on — it is chosen per call, by what you ask for, and you are billed for what comes back. Attestation is the cheapest thing on the rate card on purpose: the fewer fields you request, the less you pay and the less there is to lose.

TIER 0 · ₦15 A CHECK
Attestation

Is this NSID a currently enrolled student, and where? Yes or no, plus the institution. Enough to open a student account or price a data bundle.

verified · status
institution
No consent required · rate limited
TIER 1 · ₦50 A CHECK
Standard

What a bank, a telco or NELFUND needs to assess eligibility — including the expected completion date, so you know when to ask again instead of finding out years late.

everything in Tier 0
programme · level
expectedCompletion
Student consent required, per field
TIER 2 · ₦120 A CHECK
Identity-linked

Adds identity fields for licensed institutions with a lawful basis to hold them. The NIN is matched, never returned — you get ninMatch: true, not a number.

everything in Tier 1
name · dateOfBirth
ninMatch
KYB, mTLS and a sector licence
THE ONE THAT CATCHES PEOPLE
409 is not an error.

A consent_required response means the record exists and your key is fine — the student simply has not authorised you for those fields. Send them to the consentUrl in the body and call again when they have. Treating it as a failure is the one integration bug that produces no alert and no complaint until a student asks at a counter why they were turned away.

HTTP/1.1 409 Conflict

{
  "error": {
    "code": "CONSENT_REQUIRED",
    "message": "This student has not granted you these fields yet.",
    "consentUrl": "https://app.bona.ng/requests/cr_8f21b4",
    "requestId": "req_9f2c41a08b3e"
  }
}
Only 401, 429 and 5xx mean something went wrong, and only the last two are worth retrying. A graduated student, a lapsed record and a student in grace are all real answers.
SANDBOX FIXTURES

Every state you will meet in production exists in sandbox, including the ones that ruin naive integrations. These NSIDs carry real check characters, so they pass the same validation as production values.

NS-TEST-0001-AAAM
Active, claimed — the happy path
NS-TEST-0002-BBB4
Active but unclaimed — attestation returns, profile does not
NS-TEST-0003-CCCM
In grace, 12 days past expiry
NS-TEST-0005-EEEM
Lapsed — usually an unprocessed graduation, not a fraud signal
NS-TEST-0010-KKK9
Institution accreditation suspended — enrolment genuine, standing is not
NS-TEST-0012-NNN9
Completion date extended by a declared disruption
NS-TEST-0016-SSS9
Provisional — admitted, not yet matriculated
Sandbox also accepts X-Bona-Sandbox-Date to move the clock and X-Bona-Sandbox-Error to force a rate limit or an upstream failure, so you can test the paths you cannot otherwise reach.
SDKS
Java.NETNodePythonGoPHPOpenAPI 3.1
Plain REST over HTTPS underneath all of them. Java and .NET are listed first because that is what Nigerian bank cores run, and an SDK that assumes everyone is on Node is an SDK nobody at a bank can use.
p95 latency
112ms
Rate limit
60/min
per key
Uptime, 90 days
99.98%
Webhook replay
7 days
The public unauthenticated lookup is capped at 10 checks an hour per IP address, and every check — yours included — is written to a log the student can read in their own app. Outbound webhook delivery is the last piece of that work and is not switched on yet; the signature scheme and event names are final, so code written against them now will not need changing.
How billing works, with VAT
Five minutes from here to a verified student.

Sandbox keys on signup, a copy-pasteable call with a real NSID already in it, and a request inspector for when it goes wrong at 2am.