Understand the request. Read the response. Keep control of your product’s onboarding logic.
REST over HTTPS, JSON bodies and a Bearer key scoped to the checks it may call. Every example here uses the published sandbox values, so you can run it with a test key as it stands.
curl https://api.semperid.ng/v1/identity/nin/details \
--header "Authorization: Bearer $SEMPERID_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: signup-2291-nin" \
--data '{
"nin": "11111111110"
}'// Run on your server. Never ship your API key to a browser.
const response = await fetch(
'https://api.semperid.ng/v1/identity/nin/details',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SEMPERID_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'signup-2291-nin',
},
body: JSON.stringify({ nin: '11111111110' }),
},
);
const result = await response.json();# Run on your server. Never ship your API key to a browser.
import os
import requests
response = requests.post(
"https://api.semperid.ng/v1/identity/nin/details",
headers={
"Authorization": f"Bearer {os.environ['SEMPERID_API_KEY']}",
"Idempotency-Key": "signup-2291-nin",
},
json={"nin": "11111111110"},
timeout=30,
)
result = response.json()// Verify a delivery against the exact bytes received.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function isFromSemperID(rawBody, headers, secret) {
const timestamp = headers['semperid-timestamp'];
const signature = headers['semperid-signature'] ?? '';
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
// Also reject timestamps more than 300 seconds old.
return (
signature.length === expected.length &&
timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
);
}Call SemperID from your server only. Keep keys in your server’s secret store, never in a browser bundle, mobile app or repository.
Register in the console and create a test key for the checks you need. The secret is shown once; read it from an environment variable and never commit it.
Each check has six sandbox values: a verified result, no record, a mismatch and three provider failures. Handle all six before you go live.
Send an Idempotency-Key so a settled result is safe to retry, and verify each webhook’s HMAC-SHA256 signature before you act on it.
{
"request_id": "req_01m4f8k2v9qyx7d3h6t1c5n0wa",
"verified": true,
"data": {
"nin": "11111111110",
"first_name": "Amara",
"middle_name": "Chidinma",
"last_name": "Okafor",
"date_of_birth": "1990-04-17",
"gender": "female",
"phone_number": "08030000012",
"nationality": "NG"
}
}{
"request_id": "req_01m4f8k2v9qyx7d3h6t1c5n0wa",
"error": {
"code": "validation_error",
"message": "nin must be an 11-digit National Identification Number."
}
}Prefer to start from the contract? The full OpenAPI reference is served by the API at api.semperid.ng/docs.
Create an account, make a test key and call any of the four services against the sandbox.