Document 3 / 4

Unified KYC specification v1

Reference document for product, compliance and technical teams at partner SGIs. Architecture, levels, public API, cross-SGI portability and cryptographic audit.

1. Founding principles

2. The 3 levels

LevelRequired itemsAllowed ticket1st validation SLA
KYC1 ID document (national ID / passport) + selfie liveness + GDPR/UEMOA consent < 100,000 FCFA (~€150) < 24 business hours
KYC2 KYC1 + proof of address (< 3 months) + source of income declaration + investment profile (AMF-UMOA questionnaire) < 5,000,000 FCFA (~€7,500) < 48 business hours
KYC3 KYC2 + PEP screening + detailed source of funds + bank reference letter or tax statement Unlimited / institutional < 5 business days

3. KYC lifecycle

  1. NEW — journey initiated by the investor, draft saved automatically.
  2. PENDING — submitted, under validation (AI + conditional human review).
  3. REQUIRES_COMPLETION — missing or non-compliant document, targeted request sent to the investor.
  4. VALIDE — accepted, cryptographically sealed, usable. Valid for 12 months.
  5. REJECTED — rejected after 3 attempts or proven fraud. Investor notified with clear reason.
  6. EXPIRED — beyond 12 months without renewal.
  7. REVOKED — revoked after incident (post-validation fraud, investor request, CREPMF order).

4. Technical architecture

Components

Cross-SGI portability flow

1. Existing investor at SGI A (KYC VALIDE) → registers at SGI B
2. SGI B calls: GET /v1/kyc/by-email/{email}
   → Inopay replies: { exists: true, level: "KYC2", validated_at: "...", ... }
3. SGI B initiates: POST /v1/kyc/{id}/request-portability
   → Inopay sends an SMS/email to the investor:
     "SGI B wishes to access your KYC. Do you authorise?"
4. Investor clicks → consent recorded (logged, signed)
5. SGI B calls: GET /v1/kyc/{id}
   → Inopay delivers the signed attestation + documents (1h pre-signed URLs)
6. SGI B verifies the Ed25519 signature locally → accepted without redoing the docs
7. Inopay bills 300 FCFA reuse to SGI B

5. Main API endpoints

MethodEndpointDescription
POST/v1/kyc/sessionsCreate a KYC session for a new investor. Returns a unique URL to send to the investor.
GET/v1/kyc/:idRetrieve current state + signed attestation (if VALIDE).
GET/v1/kyc/by-email/:emailCheck existence of a reusable KYC (minimal response for privacy).
POST/v1/kyc/:id/request-portabilityRequest access to an existing KYC from another SGI.
POST/v1/kyc/:id/complementTrigger a complement request (missing document, data to refresh).
POST/v1/kyc/:id/revokeRevoke the KYC (fraud, investor request, regulatory order).
GET/v1/kyc/:id/audit-trailRetrieve the complete signed history for CREPMF audit.
POST/v1/kyc/verify-attestationVerify an Ed25519 attestation offline without a network call (optional).

6. Webhook events

7. Security & compliance

8. Quality commitments

IndicatorTarget
Auto-validation rate (without human review)≥ 75 % KYC1, ≥ 50 % KYC2
False positive rate (valid KYC rejected)< 2 %
False negative rate (fraudulent KYC validated)< 0.1 % (target: 0)
API availability99.5 % monthly
Median API response time< 300 ms

9. Interoperability

The Inopay API follows the OpenAPI 3.1 specification, documented and versioned. SGIs can generate clients in their language of choice (Node, Python, Java, Go, PHP).

The spec is exportable to a PAS-CIMA format should CIMA publish a regional KYC standard (work in progress with the Regional Council).

Version v1 — frozen on 22/04/2026. v1.x changes backward-compatible. Major evolutions (v2) with 180 days' notice + v1 support for 12 months after v2 release.