Documentation

Platform Admin KYC

Know Your Customer (KYC) management endpoints for platform administrators

Overview

Platform admin endpoints for managing KYC profiles across all tenants. These endpoints allow reviewing, approving, and rejecting KYC submissions for both customers and businesses.

KYC Profile Types

TypeDescriptionTypical Documents
CustomerIndividual person KYC verificationGovernment ID, Proof of Address, Selfie
BusinessBusiness/Company KYC verificationCertificate of Incorporation, Director IDs, Business Address Proof

KYC Statuses

StatusDescription
pendingAwaiting review by admin
under_reviewCurrently being reviewed
approvedKYC verification approved
rejectedKYC verification rejected
expiredKYC documents have expired

List Customer KYC

Retrieve customer KYC profiles across all tenants.

Endpoint

GET/api/v1/admin/kyc/customers

List all customer KYC profiles with filtering and pagination. Returns profiles across all tenants.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
statusstringNoFilter by KYC statusValues: pending, under_review, approved, rejected, expired
searchstringNoSearch by name, email, or phone number
submitted_fromstringNoFilter by submission date start (ISO 8601)
submitted_tostringNoFilter by submission date end (ISO 8601)
limitintegerNo (default: 20)Page size (max 100)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of customer KYC profiles

json
{
  "customers": [
    {
      "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
      "customer_id": "cust_660e8400-e29b-41d4-a716-446655440001",
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "full_name": "John Doe",
      "email": "john.doe@example.com",
      "phone": "+2348012345678",
      "status": "pending",
      "tier": "tier_1",
      "submitted_at": "2025-01-14T10:00:00Z",
      "reviewed_at": null,
      "created_at": "2025-01-10T08:00:00Z"
    }
  ],
  "total": 1250,
  "limit": 20,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

List Business KYC

Retrieve business KYC profiles across all tenants.

Endpoint

GET/api/v1/admin/kyc/businesses

List all business KYC profiles with filtering and pagination. Returns profiles across all tenants.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
statusstringNoFilter by KYC statusValues: pending, under_review, approved, rejected, expired
business_typestringNoFilter by business typeValues: sole_proprietorship, partnership, limited_company, ngo
searchstringNoSearch by business name or registration number
limitintegerNo (default: 20)Page size (max 100)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of business KYC profiles

json
{
  "businesses": [
    {
      "profile_id": "kyc_880e8400-e29b-41d4-a716-446655440003",
      "business_id": "biz_990e8400-e29b-41d4-a716-446655440004",
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "business_name": "Tech Solutions Ltd",
      "registration_number": "RC123456",
      "business_type": "limited_company",
      "status": "under_review",
      "tier": "tier_2",
      "submitted_at": "2025-01-13T14:30:00Z",
      "reviewed_at": null,
      "created_at": "2025-01-12T09:00:00Z"
    }
  ],
  "total": 450,
  "limit": 20,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

List KYC Requests

Retrieve all pending KYC requests awaiting review.

Endpoint

GET/api/v1/admin/kyc/requests

List KYC requests that require admin attention. Useful for review queues and dashboards.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
typestringNoFilter by profile typeValues: customer, business
statusstringNoFilter by request statusValues: pending, under_review
prioritystringNoFilter by priority levelValues: low, normal, high, urgent
sortstringNo (default: submitted_at)Sort fieldValues: submitted_at, priority, tenant_name
orderstringNo (default: asc)Sort orderValues: asc, desc
limitintegerNo (default: 20)Page size
offsetintegerNo (default: 0)Page offset

Response- Paginated list of KYC requests

json
{
  "requests": [
    {
      "request_id": "req_110e8400-e29b-41d4-a716-446655440005",
      "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
      "type": "customer",
      "name": "John Doe",
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "status": "pending",
      "priority": "normal",
      "tier_requested": "tier_2",
      "documents_count": 3,
      "submitted_at": "2025-01-14T10:00:00Z",
      "sla_deadline": "2025-01-16T10:00:00Z"
    }
  ],
  "total": 85,
  "limit": 20,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

Customer KYC Metrics

Platform-wide customer KYC verification metrics.

Endpoint

GET/api/v1/admin/kyc/customers/metrics

Get aggregated metrics for customer KYC verifications across all tenants.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter metrics by tenant UUID
start_datestringNoStart date for metrics period (ISO 8601)
end_datestringNoEnd date for metrics period (ISO 8601)
granularitystringNo (default: day)Time granularityValues: hour, day, week, month

Response- Customer KYC metrics summary

json
{
  "summary": {
    "total_profiles": 125000,
    "pending": 2500,
    "under_review": 450,
    "approved": 118000,
    "rejected": 3200,
    "expired": 850
  },
  "by_tier": {
    "tier_1": 75000,
    "tier_2": 35000,
    "tier_3": 15000
  },
  "approval_rate": 0.94,
  "avg_review_time_hours": 4.2,
  "trend": [
    {
      "date": "2025-01-13",
      "submitted": 450,
      "approved": 420,
      "rejected": 25
    },
    {
      "date": "2025-01-14",
      "submitted": 520,
      "approved": 480,
      "rejected": 30
    }
  ]
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

Business KYC Metrics

Platform-wide business KYC verification metrics.

Endpoint

GET/api/v1/admin/kyc/businesses/metrics

Get aggregated metrics for business KYC verifications across all tenants.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter metrics by tenant UUID
start_datestringNoStart date for metrics period (ISO 8601)
end_datestringNoEnd date for metrics period (ISO 8601)

Response- Business KYC metrics summary

json
{
  "summary": {
    "total_profiles": 45000,
    "pending": 800,
    "under_review": 150,
    "approved": 42000,
    "rejected": 1800,
    "expired": 250
  },
  "by_type": {
    "sole_proprietorship": 18000,
    "partnership": 8000,
    "limited_company": 17000,
    "ngo": 2000
  },
  "approval_rate": 0.91,
  "avg_review_time_hours": 8.5,
  "trend": [
    {
      "date": "2025-01-13",
      "submitted": 120,
      "approved": 105,
      "rejected": 12
    }
  ]
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

Tenant KYC Summary

Get KYC summary for a specific tenant.

Endpoint

GET/api/v1/admin/tenants/{tenantID}/kyc/summary

Get a comprehensive KYC summary for a specific tenant including counts by status and type.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
tenantIDstringYesUUID of the tenant

Response- Tenant KYC summary

json
{
  "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
  "tenant_name": "Acme Corp",
  "customers": {
    "total": 15000,
    "pending": 250,
    "under_review": 45,
    "approved": 14200,
    "rejected": 400,
    "expired": 105
  },
  "businesses": {
    "total": 2500,
    "pending": 80,
    "under_review": 15,
    "approved": 2300,
    "rejected": 85,
    "expired": 20
  },
  "compliance_score": 0.96,
  "last_updated": "2025-01-14T15:30:00Z"
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required
404tenant_not_foundTenant does not exist

KYC Profile Overview

Get a high-level overview of a KYC profile.

Endpoint

GET/api/v1/admin/kyc/{profileID}/overview

Get a summary overview of a KYC profile including status, tier, and key information.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
profileIDstringYesUUID of the KYC profile

Response- KYC profile overview

json
{
  "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
  "type": "customer",
  "status": "pending",
  "current_tier": "tier_1",
  "requested_tier": "tier_2",
  "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
  "tenant_name": "Acme Corp",
  "entity": {
    "id": "cust_660e8400-e29b-41d4-a716-446655440001",
    "name": "John Doe",
    "email": "john.doe@example.com",
    "phone": "+2348012345678"
  },
  "documents_summary": {
    "total": 3,
    "verified": 1,
    "pending": 2,
    "rejected": 0
  },
  "submitted_at": "2025-01-14T10:00:00Z",
  "sla_deadline": "2025-01-16T10:00:00Z",
  "days_pending": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
404profile_not_foundKYC profile not found

KYC Profile Details

Get complete details of a KYC profile including all documents.

Endpoint

GET/api/v1/admin/kyc/{profileID}/details

Get full details of a KYC profile including all submitted documents, verification results, and metadata.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
profileIDstringYesUUID of the KYC profile

Response- Complete KYC profile details

json
{
  "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
  "type": "customer",
  "status": "pending",
  "current_tier": "tier_1",
  "requested_tier": "tier_2",
  "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
  "entity": {
    "id": "cust_660e8400-e29b-41d4-a716-446655440001",
    "full_name": "John Doe",
    "email": "john.doe@example.com",
    "phone": "+2348012345678",
    "date_of_birth": "1990-05-15",
    "nationality": "NG",
    "address": {
      "line1": "123 Main Street",
      "city": "Lagos",
      "state": "Lagos",
      "country": "NG",
      "postal_code": "100001"
    }
  },
  "documents": [
    {
      "document_id": "doc_220e8400-e29b-41d4-a716-446655440006",
      "type": "national_id",
      "status": "verified",
      "file_url": "https://storage.example.com/docs/...",
      "extracted_data": {
        "id_number": "A12345678",
        "expiry_date": "2028-05-15"
      },
      "verified_at": "2025-01-14T11:00:00Z",
      "uploaded_at": "2025-01-14T10:00:00Z"
    },
    {
      "document_id": "doc_330e8400-e29b-41d4-a716-446655440007",
      "type": "proof_of_address",
      "status": "pending",
      "file_url": "https://storage.example.com/docs/...",
      "uploaded_at": "2025-01-14T10:05:00Z"
    },
    {
      "document_id": "doc_440e8400-e29b-41d4-a716-446655440008",
      "type": "selfie",
      "status": "pending",
      "file_url": "https://storage.example.com/docs/...",
      "liveness_score": 0.98,
      "face_match_score": 0.95,
      "uploaded_at": "2025-01-14T10:10:00Z"
    }
  ],
  "verification_checks": [
    {
      "check_type": "identity_verification",
      "status": "passed",
      "provider": "smile_id",
      "completed_at": "2025-01-14T11:00:00Z"
    },
    {
      "check_type": "address_verification",
      "status": "pending",
      "provider": "internal"
    }
  ],
  "submitted_at": "2025-01-14T10:00:00Z",
  "created_at": "2025-01-10T08:00:00Z",
  "updated_at": "2025-01-14T11:00:00Z"
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
404profile_not_foundKYC profile not found

KYC Profile History

Get the audit history of a KYC profile.

Endpoint

GET/api/v1/admin/kyc/{profileID}/history

Get the complete audit trail for a KYC profile including all status changes, document uploads, and admin actions.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
profileIDstringYesUUID of the KYC profile

Query Parameters

ParameterTypeRequiredDescription
limitintegerNo (default: 50)Number of history entries to return
offsetintegerNo (default: 0)Offset for pagination

Response- KYC profile audit history

json
{
  "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
  "history": [
    {
      "event_id": "evt_550e8400-e29b-41d4-a716-446655440009",
      "event_type": "document_uploaded",
      "description": "Selfie document uploaded",
      "actor": {
        "type": "customer",
        "id": "cust_660e8400-e29b-41d4-a716-446655440001"
      },
      "metadata": {
        "document_type": "selfie"
      },
      "timestamp": "2025-01-14T10:10:00Z"
    },
    {
      "event_id": "evt_660e8400-e29b-41d4-a716-446655440010",
      "event_type": "verification_completed",
      "description": "Identity verification passed",
      "actor": {
        "type": "system",
        "id": "smile_id"
      },
      "metadata": {
        "check_type": "identity_verification",
        "result": "passed"
      },
      "timestamp": "2025-01-14T11:00:00Z"
    },
    {
      "event_id": "evt_770e8400-e29b-41d4-a716-446655440011",
      "event_type": "status_changed",
      "description": "Status changed from draft to pending",
      "actor": {
        "type": "customer",
        "id": "cust_660e8400-e29b-41d4-a716-446655440001"
      },
      "metadata": {
        "from_status": "draft",
        "to_status": "pending"
      },
      "timestamp": "2025-01-14T10:15:00Z"
    }
  ],
  "total": 3,
  "limit": 50,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
404profile_not_foundKYC profile not found

Approve KYC

Approve a KYC profile and upgrade the entity's verification tier.

Endpoint

POST/api/v1/admin/kyc/{profileID}/approve

Approve a KYC profile. This will update the entity's verification tier and mark the profile as approved.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}
Content-TypestringYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
profileIDstringYesUUID of the KYC profile to approve

Request Body- Approval details

json
{
  "tier": "tier_2",
  "notes": "All documents verified successfully",
  "notify_entity": true
}

Response- KYC profile approved

json
{
  "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
  "status": "approved",
  "tier": "tier_2",
  "approved_at": "2025-01-14T16:00:00Z",
  "approved_by": "admin_880e8400-e29b-41d4-a716-446655440012",
  "entity_id": "cust_660e8400-e29b-41d4-a716-446655440001",
  "notification_sent": true
}

Error Responses

StatusCodeDescription
400invalid_statusProfile is not in a reviewable status
400documents_incompleteNot all required documents are verified
401unauthorizedMissing or invalid admin JWT
404profile_not_foundKYC profile not found

Request Body Parameters

FieldTypeRequiredDescription
tierstringNoTier to assign (defaults to requested tier)
notesstringNoInternal approval notes
notify_entitybooleanNoSend notification to customer/business (default: true)

Reject KYC

Reject a KYC profile with a reason.

Endpoint

POST/api/v1/admin/kyc/{profileID}/reject

Reject a KYC profile. A rejection reason is required and will be communicated to the entity if notification is enabled.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}
Content-TypestringYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
profileIDstringYesUUID of the KYC profile to reject

Request Body- Rejection details

json
{
  "reason": "document_mismatch",
  "reason_details": "The name on the ID does not match the account name",
  "documents_to_resubmit": [
    "national_id"
  ],
  "internal_notes": "Possible fraud attempt - flagged for review",
  "notify_entity": true,
  "allow_resubmission": true
}

Response- KYC profile rejected

json
{
  "profile_id": "kyc_550e8400-e29b-41d4-a716-446655440000",
  "status": "rejected",
  "rejected_at": "2025-01-14T16:30:00Z",
  "rejected_by": "admin_880e8400-e29b-41d4-a716-446655440012",
  "reason": "document_mismatch",
  "can_resubmit": true,
  "notification_sent": true
}

Error Responses

StatusCodeDescription
400invalid_statusProfile is not in a reviewable status
400reason_requiredRejection reason is required
401unauthorizedMissing or invalid admin JWT
404profile_not_foundKYC profile not found

Request Body Parameters

FieldTypeRequiredDescription
reasonstringYesRejection reason code (document_mismatch, document_expired, document_unreadable, suspicious_activity, incomplete_information)
reason_detailsstringNoHuman-readable explanation for the entity
documents_to_resubmitarrayNoList of document types that need to be resubmitted
internal_notesstringNoInternal notes (not visible to entity)
notify_entitybooleanNoSend notification to customer/business (default: true)
allow_resubmissionbooleanNoAllow the entity to resubmit (default: true)

Rejection Reason Codes

CodeDescription
document_mismatchInformation on document doesn't match provided details
document_expiredDocument has expired
document_unreadableDocument image is unclear or unreadable
suspicious_activityPotential fraud or suspicious activity detected
incomplete_informationRequired information is missing