Skip to main content

Overview

The KYC module handles identity verification for your customers. Applications flow through statuses from submission to final approval, with BVN and NIN verification steps against national identity providers.

Common Workflows

New customer onboarding: Customer submits KYC application → System verifies BVN/NIN against provider APIs → Officer reviews and approves → Customer can transact without KYC-related risk flags. Re-verification: A customer’s KYC expires → They submit updated documents → Officer verifies and approves → KYC status updates to APPROVED. Business onboarding (KYB): Officer creates KYB application → CAC lookup fetches company details → Directors verified via NIN/BVN → Beneficial owners screened against sanctions → Officer approves → Business can transact without KYB risk flags.

Permissions

ActionWho Can Do It
Submit, list, view applicationsAll authenticated users
Verify BVN/NINBANK_ADMIN, COMPLIANCE_OFFICER
Approve/reject KYCBANK_ADMIN, COMPLIANCE_OFFICER
Create KYB applicationBANK_ADMIN, COMPLIANCE_OFFICER
Run CAC lookup / verify directors / screen BOsBANK_ADMIN, COMPLIANCE_OFFICER
Approve/reject KYBBANK_ADMIN, COMPLIANCE_OFFICER

KYC Statuses

StatusMeaningRisk Impact
PENDINGSubmitted, awaiting document uploadScore 100, BLOCK
DOCUMENT_UPLOADEDID documents uploadedScore 100, BLOCK
NIN_VERIFIEDNIN check passedScore 100, BLOCK (maps to IN_PROGRESS)
BVN_VERIFIEDBVN check passedScore 100, BLOCK (maps to IN_PROGRESS)
LIVENESS_PASSEDBiometric liveness check passedScore 0, APPROVE (maps to VERIFIED)
APPROVEDFully verifiedScore 0, APPROVE
REJECTEDFailed verificationScore 100, BLOCK
EXPIREDVerification expiredScore 100, BLOCK

KYC Tiers (CBN-Compliant)

The platform supports CBN-mandated account tiers. Each tier requires a different level of identity verification:
TierRequirementsTypical Limits (CBN)
TIER_1 · BasicBVN or NIN₦20,000 single txn
TIER_2 · StandardBVN + valid ID (passport / driver’s license / voter’s card)₦500,000 max balance
TIER_3 · PremiumBVN/NIN + valid ID + proof of address + liveness checkUnlimited
Key behaviors:
  • Applications default to TIER_1 if no tier is specified at creation
  • Tier 1 requires either BVN or NIN verification
  • Tier 2 requires a linked BVN plus a valid means of identification (Passport, Driver’s License, Voter’s Card, or National ID)
  • Tier 3 adds proof of address and a liveness/biometric check
  • Smart tier default: If both BVN and NIN are provided at creation, the application defaults to TIER_2
  • Auto-upgrade: As applicants upload documents or complete verifications, the system automatically upgrades their tier when requirements are met
    • TIER_1TIER_2: requires verified BVN + valid ID (NIN alone is insufficient for Tier 2)
    • TIER_2TIER_3: requires verified BVN/NIN + valid ID + proof of address + liveness
  • The admin reviews documents uploaded by the applicant — never uploads on their behalf
  • The tier field is stored on the KYCApplication and flows into transaction screening for rule-based limit enforcement

Applicant “Comes Back” — Adding BVN/NIN Later

Not all applicants provide both BVN and NIN at creation. The system supports a resume workflow where an applicant (or officer on their behalf) can add missing identity numbers to an existing PENDING application. Scenario:
  1. Applicant creates application with only name and phone → Status: PENDING, Tier: TIER_1
  2. Later, applicant provides their NIN via mobile app or branch visit
  3. Officer uses PATCH /api/v1/kyc/applications/:id to add the NIN
  4. Officer clicks “Verify NIN” → Status becomes NIN_VERIFIED
  5. Applicant is now Tier 1 approved (or can proceed to Tier 2/3)
# Officer adds missing NIN to an existing application
PATCH /api/v1/kyc/applications/kyc_abc123
{
  "nin": "12345678901"
}

# Then verify it
POST /api/v1/kyc/applications/kyc_abc123/verify-nin
{
  "nin": "12345678901",
  "firstName": "Chinedu",
  "lastName": "Obi",
  "dateOfBirth": "1990-03-15"
}
Editable fields: nin, bvn, email, phone, dateOfBirth Allowed statuses: PENDING, DOCUMENT_UPLOADED, NIN_VERIFIED, BVN_VERIFIED Validation: NIN and BVN must be exactly 11 digits; empty strings clear the field; invalid dates are rejected Smart tier bump: If both BVN and NIN become present, tier auto-bumps to TIER_2. If documents/verifications already exist, auto-upgrade is also evaluated.

Status Preservation During Verification

The KYC status field tracks the highest verified milestone reached. Verifying an identity type never downgrades a higher status:
Current StatusVerify NINVerify BVNResult
PENDINGNIN_VERIFIEDBVN_VERIFIEDNormal progression
NIN_VERIFIEDNIN_VERIFIEDBVN_VERIFIEDUpgrades to BVN
BVN_VERIFIEDstays BVN_VERIFIEDBVN_VERIFIEDNIN does not downgrade
LIVENESS_PASSEDstays LIVENESS_PASSEDstays LIVENESS_PASSEDPreserves highest milestone
This ensures a Tier 2 application at BVN_VERIFIED remains approvable even if NIN is later verified, and a Tier 3 application at LIVENESS_PASSED remains approvable if additional identity checks are run.

Tier Upgrade Flow

  1. Applicant is approved at Tier 1 (NIN verified only)
  2. Later, they provide BVN → Admin clicks “Upgrade to Tier 2”
  3. System resets status to NIN_VERIFIED (preserving the verified NIN)
  4. Admin verifies the BVN → Status becomes BVN_VERIFIED
  5. Admin approves → Application is now Tier 2 · Approved

BYOL Provider Tier Limits

If a tenant uses BYOL (Bring Your Own License), their provider may not support all verification types needed for higher tiers. Configure maxTier and supportedVerifications in the BYOL config:
{
  "providerName": "SmileIdentity",
  "maxTier": "TIER_1",
  "supportedVerifications": ["nin", "bvn"]
  // ... rest of config
}
If a tenant requests Tier 2/3 but their BYOL provider’s maxTier is lower:
  • With kycFallbackMode = WALLET_RESERVE: Platform automatically falls back to embedded providers for the missing verification types
  • With kycFallbackMode = NONE: The verification is blocked with a clear error message

KYC Endpoints

MethodEndpointDescription
POST/api/v1/kyc/applicationsSubmit a KYC application
GET/api/v1/kyc/applicationsList applications
GET/api/v1/kyc/applications/:idRetrieve application details
PATCH/api/v1/kyc/applications/:idUpdate identity fields
POST/api/v1/kyc/applications/:id/verify-bvnVerify applicant BVN
POST/api/v1/kyc/applications/:id/verify-ninVerify applicant NIN
POST/api/v1/kyc/applications/:id/liveness-checkRun biometric liveness check
POST/api/v1/kyc/applications/:id/documentsUpload document to MinIO
GET/api/v1/kyc/applications/:id/documentsList uploaded documents
GET/api/v1/kyc/applications/:id/documents/:docId/downloadGet presigned download URL
DELETE/api/v1/kyc/applications/:id/documents/:docIdDelete document from MinIO
PATCH/api/v1/kyc/applications/:id/approveApprove application
PATCH/api/v1/kyc/applications/:id/rejectReject application
POST/api/v1/kyc/applications/:id/upgrade-tierUpgrade to Tier 2 or 3
GET/api/v1/kyc/applications/:id/tier-requirementsCheck tier requirements

KYB Statuses

StatusMeaningRisk Impact
PENDINGApplication submitted, awaiting CAC lookupScore 100, BLOCK
CAC_VERIFIEDCAC lookup successfulScore 100, BLOCK
DIRECTORS_VERIFIEDDirectors identity verifiedScore 100, BLOCK
BENEFICIAL_OWNERS_VERIFIEDBeneficial owners screenedScore 100, BLOCK
DOCUMENT_UPLOADEDSupporting documents uploadedScore 100, BLOCK
SCREENING_PASSEDAll compliance checks passedScore 100, BLOCK
APPROVEDFully verifiedScore 0, APPROVE
REJECTEDFailed verification or sanctions hitScore 100, BLOCK
Note: KYB is a hard prerequisite for business transactions. Only APPROVED status allows transactions to proceed without risk flags. All intermediate statuses score 100 and result in BLOCK.

Per-Tenant KYC Provider Configuration

Each tenant can independently configure how identity verification is performed.

Provider Modes

ModeDescription
EMBEDDEDUses platform-managed providers. Default for all new tenants.
BYOLUses the tenant’s own KYC provider API, configured via JSON.

Switching Provider Mode

BANK_ADMIN users can switch modes from Dashboard → Settings → KYC Provider:
  1. Select Embedded or BYOL from the dropdown.
  2. If BYOL, fill in the configuration form:
    • Provider Name
    • Base URL
    • API Key / App ID
    • Endpoint paths for NIN, BVN, and Liveness
    • Request/response field mappings
    • Match confidence threshold
  3. Save -the change takes effect immediately for all new verifications.

BYOL Configuration Format

The configuration is stored as JSON in Tenant.kycProviderConfig:
{
  "providerName": "SmileIdentity",
  "baseUrl": "https://api.smileidentity.com/v1",
  "headers": { "Authorization": "Bearer sk_xxx" },
  "endpoints": {
    "nin": "/id_verification",
    "bvn": "/id_verification",
    "liveness": "/biometric"
  },
  "methods": { "nin": "POST", "bvn": "POST" },
  "requestMapping": {
    "nin": { "id_number": "nin", "id_type": "'NIN'" },
    "bvn": { "id_number": "bvn", "id_type": "'BVN'" }
  },
  "responseMapping": {
    "firstNamePath": "result.first_name",
    "lastNamePath": "result.last_name"
  },
  "matchConfidence": 92
}

KYC Endpoints

MethodEndpointDescription
POST/api/v1/kyc/applicationsSubmit a KYC application
GET/api/v1/kyc/applicationsList applications
GET/api/v1/kyc/applications/:idRetrieve application details
POST/api/v1/kyc/applications/:id/verify-bvnVerify applicant BVN
POST/api/v1/kyc/applications/:id/verify-ninVerify applicant NIN
POST/api/v1/kyc/applications/:id/liveness-checkRun biometric liveness check
POST/api/v1/kyc/applications/:id/documentsUpload document to MinIO
GET/api/v1/kyc/applications/:id/documentsList uploaded documents
GET/api/v1/kyc/applications/:id/documents/:docId/downloadGet presigned download URL
DELETE/api/v1/kyc/applications/:id/documents/:docIdDelete document from MinIO
PATCH/api/v1/kyc/applications/:id/approveApprove application
PATCH/api/v1/kyc/applications/:id/rejectReject application

KYB Endpoints

MethodEndpointDescription
POST/api/v1/kyc/kyb/applicationsCreate a KYB application
GET/api/v1/kyc/kyb/applicationsList KYB applications
GET/api/v1/kyc/kyb/applications/:idGet KYB application details
POST/api/v1/kyc/kyb/applications/:id/verify-cacRun CAC lookup by RC number
POST/api/v1/kyc/kyb/applications/:id/verify-directorsVerify all directors via KYC
POST/api/v1/kyc/kyb/applications/:id/screen-beneficial-ownersScreen BOs against sanctions
POST/api/v1/kyc/kyb/applications/:id/documentsUpload KYB document to MinIO
GET/api/v1/kyc/kyb/applications/:id/documentsList KYB uploaded documents
GET/api/v1/kyc/kyb/applications/:id/documents/:docId/downloadGet presigned download URL
DELETE/api/v1/kyc/kyb/applications/:id/documents/:docIdDelete KYB document from MinIO
PATCH/api/v1/kyc/kyb/applications/:id/approveApprove KYB application
PATCH/api/v1/kyc/kyb/applications/:id/rejectReject KYB application

Tenant Configuration Endpoints

MethodEndpointDescription
PATCH/api/v1/tenants/meUpdate tenant config including kycProviderMode, kycProviderConfig, kycTrustMode, and byolFallbackMode

Submit KYC Application

Create a new KYC application for a customer. Request Body
FieldTypeRequiredDescription
entityTypestringINDIVIDUAL or BUSINESS
firstNamestringApplicant first name
lastNamestringApplicant last name
bvnstringBank Verification Number
ninstringNational Identity Number
phonestringMobile number with country code
emailstringEmail address
dateOfBirthstringISO 8601 date (e.g. "1990-03-15")
tierstringTIER_1, TIER_2, or TIER_3. Defaults to TIER_1
Example Request
curl -X POST /v1/kyc/applications \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "entityType": "INDIVIDUAL",
    "firstName": "Chinedu",
    "lastName": "Obi",
    "bvn": "22012345678",
    "nin": "12345678901",
    "phone": "+2348012345678",
    "email": "chinedu.obi@email.com",
    "dateOfBirth": "1990-03-15"
  }'
Example Response -201 Created
{
  "success": true,
  "data": {
    "id": "kyc_abc123",
    "tenantId": "660e8400-e29b-41d4-a716-446655440001",
    "entityType": "INDIVIDUAL",
    "firstName": "Chinedu",
    "lastName": "Obi",
    "bvn": "22012345678",
    "nin": "12345678901",
    "phone": "+2348012345678",
    "email": "chinedu.obi@email.com",
    "dateOfBirth": "1990-03-15T00:00:00Z",
    "status": "PENDING",
    "riskLevel": null,
    "assignedTo": null,
    "notes": null,
    "createdAt": "2026-05-16T08:00:00Z",
    "updatedAt": "2026-05-16T08:00:00Z"
  }
}

Create KYB Application

Create a new KYB application for a corporate entity. Request Body
FieldTypeRequiredDescription
companyNamestringRegistered company name
rcNumberstringCAC registration number
tinstringTax Identification Number
addressstringRegistered business address
incorporationDatestringISO 8601 date
directorsarrayArray of director objects
directors[].namestringDirector full name
directors[].bvnstringDirector BVN
directors[].ninstringDirector NIN
directors[].emailstringDirector email
directors[].phonestringDirector phone
directors[].nationalitystringDirector nationality
beneficialOwnersarrayArray of beneficial owner objects
beneficialOwners[].namestringOwner full name
beneficialOwners[].percentagenumberOwnership percentage
beneficialOwners[].bvnstringOwner BVN
beneficialOwners[].ninstringOwner NIN
Example Request
curl -X POST /v1/kyc/kyb/applications \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "companyName": "Acme Nigeria Ltd",
    "rcNumber": "RC123456",
    "tin": "12345678-0001",
    "address": "15 Broad Street, Lagos",
    "incorporationDate": "2015-06-12",
    "directors": [
      { "name": "John Doe", "bvn": "22012345678", "email": "john@acme.ng" }
    ],
    "beneficialOwners": [
      { "name": "Jane Smith", "percentage": 75, "bvn": "22087654321" }
    ]
  }'

Verify CAC

Run a CAC lookup for a KYB application. Path Parameters
ParameterTypeDescription
idstringKYB Application UUID
Request Body
FieldTypeRequiredDescription
rcNumberstringCAC registration number to look up
Example Request
curl -X POST /v1/kyc/kyb/applications/kyb_abc123/verify-cac \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "rcNumber": "RC123456"
  }'
Example Response -200 OK
{
  "success": true,
  "data": {
    "id": "kyb_abc123",
    "status": "CAC_VERIFIED",
    "companyName": "Acme Nigeria Ltd",
    "rcNumber": "RC123456",
    "directors": [{ "name": "John Doe", "role": "Director" }],
    "beneficialOwners": [{ "name": "Jane Smith", "percentage": 75 }],
    "updatedAt": "2026-05-16T09:00:00Z"
  }
}

List KYC Applications

Query Parameters
ParameterTypeDefaultDescription
statusstring-Filter by status
pageinteger1Page number
limitinteger20Items per page
Example Request
curl -X GET "/v1/kyc/applications?status=PENDING&page=1&limit=10" \
  -H "Authorization: Bearer <access_token>"
Example Response -200 OK
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "kyc_abc123",
        "entityType": "INDIVIDUAL",
        "firstName": "Chinedu",
        "lastName": "Obi",
        "status": "PENDING",
        "riskLevel": null,
        "createdAt": "2026-05-16T08:00:00Z",
        "updatedAt": "2026-05-16T08:00:00Z"
      }
    ],
    "total": 5,
    "page": 1,
    "limit": 10,
    "totalPages": 1
  }
}

Get KYC Application

Retrieve a KYC application with full verification results and uploaded documents. Example Request
curl -X GET /v1/kyc/applications/kyc_abc123 \
  -H "Authorization: Bearer <access_token>"
Example Response -200 OK
{
  "success": true,
  "data": {
    "id": "kyc_abc123",
    "tenantId": "660e8400-e29b-41d4-a716-446655440001",
    "entityType": "INDIVIDUAL",
    "status": "BVN_VERIFIED",
    "firstName": "Chinedu",
    "lastName": "Obi",
    "bvn": "22012345678",
    "nin": "12345678901",
    "phone": "+2348012345678",
    "email": "chinedu.obi@email.com",
    "dateOfBirth": "1990-03-15T00:00:00Z",
    "riskLevel": null,
    "assignedTo": null,
    "notes": null,
    "createdAt": "2026-05-16T08:00:00Z",
    "updatedAt": "2026-05-16T09:00:00Z",
    "verificationResults": [
      {
        "id": "vr_001",
        "applicationId": "kyc_abc123",
        "identityType": "BVN",
        "provider": "PREMBLY",
        "isMatch": true,
        "confidence": 0.95,
        "rawResponse": null,
        "errorMessage": null,
        "verifiedAt": "2026-05-16T09:00:00Z"
      }
    ],
    "documents": [
      {
        "id": "doc_001",
        "applicationId": "kyc_abc123",
        "documentType": "PASSPORT",
        "fileName": "passport.pdf",
        "fileUrl": "kyc-documents/passport-123.pdf",
        "fileSizeBytes": 204800,
        "mimeType": "application/pdf",
        "uploadedAt": "2026-05-16T08:30:00Z"
      }
    ]
  }
}

Verify BVN

Trigger BVN verification against the identity provider. Path Parameters
ParameterTypeDescription
idstringApplication UUID
Request Body
FieldTypeRequiredDescription
bvnstringBVN to verify (11 digits)
firstNamestringFirst name for cross-match
lastNamestringLast name for cross-match
dateOfBirthstringDate of birth for cross-match
Example Request
curl -X POST /v1/kyc/applications/kyc_abc123/verify-bvn \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "bvn": "22012345678",
    "firstName": "Chinedu",
    "lastName": "Obi",
    "dateOfBirth": "1990-03-15"
  }'
Example Response -200 OK
{
  "success": true,
  "data": {
    "isMatch": true,
    "confidence": 0.95,
    "provider": "PREMBLY",
    "providerSource": "EMBEDDED",
    "newStatus": "BVN_VERIFIED"
  }
}
Auto-upgrade behavior: If the applicant has already uploaded a valid ID document, successful BVN verification may auto-upgrade the application from Tier 1 to Tier 2.

Verify NIN

Trigger NIN verification. Path Parameters
ParameterTypeDescription
idstringApplication UUID
Request Body
FieldTypeRequiredDescription
ninstringNIN to verify (11 digits)
firstNamestringFirst name for cross-match
lastNamestringLast name for cross-match
dateOfBirthstringDate of birth for cross-match
Example Request
curl -X POST /v1/kyc/applications/kyc_abc123/verify-nin \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "nin": "12345678901",
    "firstName": "Chinedu",
    "lastName": "Obi",
    "dateOfBirth": "1990-03-15"
  }'
  • Example Response — 200 OK
{
  "success": true,
  "data": {
    "isMatch": true,
    "confidence": 0.94,
    "provider": "PREMBLY",
    "providerSource": "EMBEDDED",
    "newStatus": "NIN_VERIFIED"
  }
}

Liveness Check

Run a biometric liveness and face-match check. Path Parameters
ParameterTypeDescription
idstringApplication UUID
Request Body
FieldTypeRequiredDescription
selfieImageBase64stringBase64-encoded selfie image (JPEG/PNG)
documentImageBase64stringBase64-encoded ID document for face-match
Example Request
curl -X POST /v1/kyc/applications/kyc_abc123/liveness-check \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "selfieImageBase64": "/9j/4AAQSkZJRgABAQEASABIAAD...",
    "documentImageBase64": "/9j/4AAQSkZJRgABAQEASABIAAD..."
  }'
```-

**Example Response — 200 OK**

```json
{
  "success": true,
  "data": {
    "isLive": true,
    "confidence": 0.97,
    "faceMatch": true,
    "faceMatchConfidence": 0.92,
    "provider": "PREMBLY",
    "providerSource": "EMBEDDED",
    "newStatus": "LIVENESS_PASSED"
  }
}
Auto-upgrade behavior: If the applicant has already uploaded a valid ID and proof of address, successful liveness verification may auto-upgrade the application from Tier 2 to Tier 3.

Approve Application

Final approval of a KYC application. Path Parameters
ParameterTypeDescription
idstringApplication UUID
Example Request
curl -X PATCH /v1/kyc/applications/kyc_abc123/approve \
  -H "Authorization: Bearer <access_token>"
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "kyc_abc123",
    "status": "APPROVED",
    "riskLevel": "LOW",
    "updatedAt": "2026-05-16T10:00:00Z"
  }
}
Approving a KYC application updates the customer’s risk profile. Future transactions from this customer will reflect the APPROVED status.

Reject Application

Reject a KYC application that fails verification. Path Parameters
ParameterTypeDescription
idstringApplication UUID
Request Body
FieldTypeRequiredDescription
reasonstringReason for rejection
Example Request
curl -X PATCH /v1/kyc/applications/kyc_abc123/reject \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "BVN name mismatch. Uploaded document appears fraudulent."
  }'-
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "kyc_abc123",
    "status": "REJECTED",
    "riskLevel": "HIGH",
    "notes": "BVN name mismatch. Uploaded document appears fraudulent.",
    "updatedAt": "2026-05-16T10:00:00Z"
  }
}

Verify Directors

Verify each director’s identity via BVN/NIN against identity providers. Path Parameters
ParameterTypeDescription
idstringKYB Application UUID
Request Body
FieldTypeRequiredDescription
directorsarrayArray of director objects
directors[].namestringDirector full name
directors[].ninstringDirector NIN
directors[].bvnstringDirector BVN
directors[].verifiedbooleanPre-verified flag
Example Request
curl -X POST /v1/kyc/kyb/applications/kyb_abc123/verify-directors \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "directors": [
      { "name": "John Doe", "nin": "12345678901", "bvn": "22012345678", "verified": true }
    ]
  }'-
Example Response — 200 OK
{
  "success": true,
  "data": {
    "allVerified": true,
    "directors": [
      {
        "name": "John Doe",
        "nin": "12345678901",
        "bvn": "22012345678",
        "verified": true
      }
    ],
    "newStatus": "DIRECTORS_VERIFIED"
  }
}

Screen Beneficial Owners

Screen beneficial owners against global sanctions and PEP watchlists. Path Parameters
ParameterTypeDescription
idstringKYB Application UUID
Request Body
FieldTypeRequiredDescription
beneficialOwnersarrayArray of BO objects
beneficialOwners[].namestringOwner full name
beneficialOwners[].cleanbooleanPre-screened clean flag
beneficialOwners[].hitsarrayWatchlist hits if not clean
Example Request
curl -X POST /v1/kyc/kyb/applications/kyb_abc123/screen-beneficial-owners \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "beneficialOwners": [
      { "name": "Jane Smith", "clean": true, "hits": [] }
    ]
  }'-
Example Response — 200 OK
{
  "success": true,
  "data": {
    "allClean": true,
    "beneficialOwners": [{ "name": "Jane Smith", "clean": true, "hits": [] }],
    "newStatus": "BENEFICIAL_OWNERS_VERIFIED"
  }
}

Approve KYB Application

Final approval of a KYB application. Requires BANK_ADMIN or COMPLIANCE_OFFICER role. Path Parameters
ParameterTypeDescription
idstringKYB Application UUID
Example Request
curl -X PATCH /v1/kyc/kyb/applications/kyb_abc123/approve \
  -H "Authorization: Bearer <access_token>"
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "kyb_abc123",
    "status": "APPROVED",
    "riskLevel": "LOW",
    "updatedAt": "2026-05-16T10:00:00Z"
  }
}
Approving a KYB application updates the business entity’s risk profile. Future transactions from this entity will reflect the APPROVED status (score 0, no KYB-related risk).

Reject KYB Application

Reject a KYB application that fails verification. Requires BANK_ADMIN or COMPLIANCE_OFFICER role. Path Parameters
ParameterTypeDescription
idstringKYB Application UUID
Request Body
FieldTypeRequiredDescription
reasonstringReason for rejection
Example Request
curl -X PATCH /v1/kyc/kyb/applications/kyb_abc123/reject \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Sanctions hit on beneficial owner Jane Smith."
  }'-
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "kyb_abc123",
    "status": "REJECTED",
    "riskLevel": "HIGH",
    "notes": "Sanctions hit on beneficial owner Jane Smith.",
    "updatedAt": "2026-05-16T10:00:00Z"
  }
}

KYC Document Upload

Upload, manage, and retrieve KYC application documents stored in MinIO (S3-compatible object storage).

Upload KYC Document

POST /api/v1/kyc/applications/:id/documents Upload a file to MinIO and attach it to a KYC application. Path Parameters
ParameterTypeDescription
idstringKYC Application UUID
Request Body (multipart/form-data)
FieldTypeRequiredDescription
filefileThe file to upload (PDF, JPG, PNG, max 10MB)
documentTypestringPASSPORT, NATIONAL_ID, DRIVERS_LICENSE, VOTERS_CARD, UTILITY_BILL, BANK_STATEMENT, SELFIE, LIVENESS_VIDEO, SIGNATURE, OTHER
Example Request
curl -X POST /v1/kyc/applications/kyc_abc123/documents \
  -H "Authorization: Bearer <access_token>" \
  -F "file=@/path/to/passport.pdf" \
  -F "documentType=PASSPORT"
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "doc_001",
    "documentType": "PASSPORT",
    "fileName": "passport.pdf",
    "fileSizeBytes": 204800,
    "mimeType": "application/pdf",
    "uploadedAt": "2026-05-16T08:30:00Z",
    "presignedUrl": "documents/kyc/kyc_abc123/1715851200000-passport.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256..."
  }
}
Auto-upgrade behavior: After a document is uploaded, the system automatically checks if the applicant now meets the requirements for a higher tier. For example, uploading a PASSPORT after BVN verification may auto-upgrade the application from Tier 1 to Tier 2.

List KYC Documents

GET /api/v1/kyc/applications/:id/documents List all documents for a KYC application with presigned URLs. Example Response — 200 OK
{
  "success": true,
  "data": [
    {
      "id": "doc_001",
      "documentType": "PASSPORT",
      "fileName": "passport.pdf",
      "fileSizeBytes": 204800,
      "mimeType": "application/pdf",
      "uploadedAt": "2026-05-16T08:30:00Z",
      "presignedUrl": "documents/kyc/kyc_abc123/1715851200000-passport.pdf?X-Amz-Algorithm=..."
    }
  ]
}

Get KYC Document Download URL

GET /api/v1/kyc/applications/:id/documents/:docId/download Get a time-limited presigned URL to download a document directly from MinIO. Path Parameters
ParameterTypeDescription
idstringKYC Application UUID
docIdstringDocument UUID
Example Response — 200 OK
{
  "success": true,
  "data": {
    "url": "documents/kyc/kyc_abc123/1715851200000-passport.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256...",
    "expiresIn": 300
  }
}

Delete KYC Document

DELETE /api/v1/kyc/applications/:id/documents/:docId Delete a document from MinIO and the database. Requires BANK_ADMIN or COMPLIANCE_OFFICER role. Example Response — 200 OK
{
  "success": true,
  "data": { "deleted": true }
}

KYB Document Upload

Upload, manage, and retrieve KYB application documents stored in MinIO.

Upload KYB Document

POST /api/v1/kyc/kyb/applications/:id/documents Request Body (multipart/form-data)
FieldTypeRequiredDescription
filefileThe file to upload (PDF, JPG, PNG, max 10MB)
documentTypestringCAC_CERTIFICATE, MEMART, TAX_CLEARANCE, BOARD_RESOLUTION, AUDITED_ACCOUNTS, UTILITY_BILL, DIRECTOR_ID, BENEFICIAL_OWNER_ID, OTHER
Example Request
curl -X POST /v1/kyc/kyb/applications/kyb_abc123/documents \
  -H "Authorization: Bearer <access_token>" \
  -F "file=@/path/to/cac_certificate.pdf" \
  -F "documentType=CAC_CERTIFICATE"
Example Response — 200 OK
{
  "success": true,
  "data": {
    "id": "doc_kyb_001",
    "documentType": "CAC_CERTIFICATE",
    "fileName": "cac_certificate.pdf",
    "fileSizeBytes": 512000,
    "mimeType": "application/pdf",
    "uploadedAt": "2026-05-16T09:00:00Z",
    "presignedUrl": "documents/kyb/kyb_abc123/1715853000000-cac_certificate.pdf?X-Amz-Algorithm=..."
  }
}

List KYB Documents

GET /api/v1/kyc/kyb/applications/:id/documents List all documents for a KYB application with presigned URLs. Example Response — 200 OK
{
  "success": true,
  "data": [
    {
      "id": "doc_kyb_001",
      "documentType": "CAC_CERTIFICATE",
      "fileName": "cac_certificate.pdf",
      "fileSizeBytes": 512000,
      "mimeType": "application/pdf",
      "uploadedAt": "2026-05-16T09:00:00Z",
      "presignedUrl": "documents/kyb/kyb_abc123/1715853000000-cac_certificate.pdf?X-Amz-Algorithm=..."
    }
  ]
}

Get KYB Document Download URL

GET /api/v1/kyc/kyb/applications/:id/documents/:docId/download Get a time-limited presigned URL to download a KYB document. Example Response — 200 OK
{
  "success": true,
  "data": {
    "url": "documents/kyb/kyb_abc123/1715853000000-cac_certificate.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256...",
    "expiresIn": 300
  }
}

Delete KYB Document

DELETE /api/v1/kyc/kyb/applications/:id/documents/:docId Delete a KYB document from MinIO and the database. Requires BANK_ADMIN or COMPLIANCE_OFFICER role. Example Response — 200 OK
{
  "success": true,
  "data": { "deleted": true }
}