Skip to main content

KYC Verification

Verify your customers' identities using various verification methods including BVN, NIN, phone, and document verification.

Verification Types

TypeDescriptionCountries
bvnBank Verification NumberNigeria
ninNational Identification NumberNigeria
phonePhone number verificationAll
passportInternational passportAll
drivers_licenseDriver's licenseAll
voters_cardVoter's cardNigeria

Submit Verification

BVN Verification

curl -X POST https://api.lanonasis.com/v1/kyc/verify \
-H "X-API-Key: sk_live_xxx" \
-H "Idempotency-Key: kyc_cust123_bvn" \
-H "Content-Type: application/json" \
-d '{
"type": "bvn",
"value": "22222222222",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1990-05-15"
}'

Response

{
"success": true,
"data": {
"id": "ver_abc123",
"type": "bvn",
"status": "verified",
"match": true,
"confidence": 100,
"data": {
"first_name": "JOHN",
"last_name": "DOE",
"middle_name": "SMITH",
"date_of_birth": "1990-05-15",
"phone_number": "+2348012345678",
"gender": "male",
"nationality": "Nigerian",
"photo_url": "https://storage.lanonasis.com/kyc/photos/abc123.jpg"
},
"verified_at": "2024-01-15T14:30:00Z"
}
}

NIN Verification

curl -X POST https://api.lanonasis.com/v1/kyc/verify \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "nin",
"value": "12345678901",
"first_name": "John",
"last_name": "Doe"
}'

Phone Verification

curl -X POST https://api.lanonasis.com/v1/kyc/verify \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "phone",
"value": "+2348012345678"
}'

Phone verification returns carrier information:

{
"success": true,
"data": {
"id": "ver_xyz789",
"type": "phone",
"status": "verified",
"match": true,
"data": {
"phone_number": "+2348012345678",
"carrier": "MTN Nigeria",
"line_type": "mobile",
"is_active": true,
"is_ported": false
}
}
}

Verification Statuses

StatusDescription
verifiedVerification successful, data matches
failedVerification failed or data doesn't match
pendingVerification in progress (async)
expiredVerification result expired

Match vs Verification

  • status: "verified" means we successfully retrieved the data
  • match: true means the provided details match the retrieved data
{
"status": "verified",
"match": false,
"data": {
"first_name": "JOHN",
"last_name": "DOE"
}
}

The above means: BVN is valid, but the name provided doesn't match.

Get Verification Status

curl https://api.lanonasis.com/v1/kyc/ver_abc123 \
-H "X-API-Key: sk_live_xxx"

Business Verification

Verify business registration (CAC) and tax identification (TIN):

CAC Verification

curl -X POST https://api.lanonasis.com/v1/kyc/verify \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "cac",
"value": "RC123456",
"business_name": "Acme Corporation Ltd"
}'

Response

{
"success": true,
"data": {
"id": "ver_biz123",
"type": "cac",
"status": "verified",
"match": true,
"data": {
"registration_number": "RC123456",
"business_name": "ACME CORPORATION LIMITED",
"registration_date": "2015-03-20",
"business_status": "active",
"business_address": "123 Business Avenue, Lagos",
"directors": [
{
"name": "John Doe",
"designation": "Director"
}
]
}
}
}

Sandbox Testing

Use these test values in sandbox:

TypeTest ValueResult
BVN22222222222Success, verified
BVN11111111111Failed, not found
NIN12345678901Success, verified
Phone+2348000000000Success, verified

Confidence Scores

Verification results include a confidence score (0-100):

ScoreMeaning
90-100High confidence match
70-89Good match with minor discrepancies
50-69Partial match, review recommended
0-49Poor match, likely different person

SDK Examples

TypeScript

import { LanOnasisClient } from '@lanonasis/sdk';

const client = new LanOnasisClient({ apiKey: 'sk_live_xxx' });

// BVN Verification
const bvnResult = await client.kyc.verify({
type: 'bvn',
value: '22222222222',
first_name: 'John',
last_name: 'Doe',
date_of_birth: '1990-05-15'
});

if (bvnResult.data.status === 'verified' && bvnResult.data.match) {
console.log('Customer verified!');
console.log('Photo URL:', bvnResult.data.data.photo_url);
}

// Phone Verification
const phoneResult = await client.kyc.verify({
type: 'phone',
value: '+2348012345678'
});

console.log('Carrier:', phoneResult.data.data.carrier);

Python

from lanonasis import LanOnasisClient

client = LanOnasisClient(api_key='sk_live_xxx')

# BVN Verification
result = client.kyc.verify(
type='bvn',
value='22222222222',
first_name='John',
last_name='Doe',
date_of_birth='1990-05-15'
)

if result.data.status == 'verified' and result.data.match:
print('Customer verified!')
print(f"Photo: {result.data.data.photo_url}")

Best Practices

  1. Collect consent - Always get customer consent before verification
  2. Secure storage - Don't store raw BVN/NIN values
  3. Use idempotency keys - Prevent duplicate verification charges
  4. Handle failures gracefully - Allow manual verification as fallback

Webhooks

Subscribe to KYC events:

  • kyc.submitted - Verification submitted
  • kyc.verified - Successfully verified
  • kyc.failed - Verification failed

See Webhooks for details.