API REFERENCE

Documentation API

Bienvenue dans la documentation officielle de VerifyPro Africa. Notre API REST vous permet d'intégrer la vérification d'identité dans n'importe quelle application web, mobile ou backend.

API Key

Authentification simple par Bearer token

< 3 secondes

Temps de traitement moyen

HTTPS only

Toutes les requêtes chiffrées TLS 1.3

URL de base : https://verifyproafrica.lfdweb.com/api/v1

Authentification

Toutes les requêtes doivent inclure votre clé API dans le header Authorization.

Authorization: Bearer vpa_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠ Mode test : Les clés commençant par vpa_test_ ne consomment pas votre quota et retournent des données fictives réalistes.

🔒 Sécurité : Ne jamais exposer vos clés API dans votre frontend ou dans un dépôt Git. Utilisez des variables d'environnement.

Démarrage rapide

Vérifiez votre première identité en moins de 5 minutes.

1

Créez votre compte et obtenez une clé API

Inscrivez-vous sur verifyproafrica.lfdweb.com et créez votre première clé API depuis le dashboard.

2

Lancez votre première vérification

curl -X POST https://verifyproafrica.lfdweb.com/api/v1/verify \
  -H "Authorization: Bearer vpa_test_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "email": "test@exemple.com"
  }'
3

Recevez le résultat

{
  "id": "vrf_abc123",
  "status": "completed",
  "type": "email",
  "overallScore": 85,
  "riskLevel": "low",
  "fraudDetected": false,
  "emailResult": {
    "valid": true,
    "disposable": false,
    "mxValid": true,
    "riskScore": 15
  },
  "completedAt": "2025-01-15T10:30:00.000Z",
  "isTestMode": true
}

Vérification d'identité

POSThttps://verifyproafrica.lfdweb.com/api/v1/verifyLance une vérification

Paramètres du corps (JSON)

ChampTypeRequisDescription
typestringType de vérification (voir section Types)
documentTypestringCond.national_id, passport, driving_license, residence_permit
documentImagestringCond.Image base64 du document (JPG/PNG, max 10 Mo)
selfieImagestringCond.Selfie base64 pour la comparaison faciale
videoFramesstring[]Cond.Frames vidéo base64 pour la détection de vivacité
emailstringCond.Email à vérifier
phonestringCond.Numéro de téléphone avec indicatif (+229...)
firstNamestringPrénom pour la vérification AML
lastNamestringNom pour la vérification AML
countrystringCode pays ISO 3166-1 alpha-2

Exemple — KYC Complet

const response = await fetch('https://verifyproafrica.lfdweb.com/api/v1/verify', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vpa_live_votre_cle',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: 'full-kyc',
    documentType: 'national_id',
    documentImage: documentBase64,
    selfieImage: selfieBase64,
    email: 'client@exemple.com',
    phone: '+229 96 00 00 00',
    country: 'BJ'
  })
});

const result = await response.json();
console.log(result.overallScore);   // 92
console.log(result.riskLevel);      // "low"
console.log(result.fraudDetected);  // false

Réponse

{
  "id": "vrf_7f3a9b2c",
  "status": "completed",
  "type": "full-kyc",
  "overallScore": 92,
  "riskLevel": "low",
  "fraudDetected": false,
  "extractedData": {
    "firstName": "KOFI",
    "lastName": "MENSAH",
    "birthDate": "15/03/1990",
    "docNumber": "BJ1234567",
    "expiryDate": "14/03/2030",
    "nationality": "BEN",
    "expired": false,
    "tamperingDetected": false,
    "confidenceScore": 0.97
  },
  "faceMatch": {
    "matched": true,
    "similarityScore": 0.94,
    "livenessConfirmed": false
  },
  "emailResult": { "valid": true, "disposable": false, "mxValid": true, "riskScore": 10 },
  "phoneResult": { "valid": true, "country": "Bénin", "lineType": "mobile", "riskScore": 10 },
  "amlResult": { "sanctionsMatch": false, "pepMatch": false, "kycRiskScore": 0 },
  "completedAt": "2025-01-15T10:30:01.234Z",
  "isTestMode": false
}

Sessions — Lien de vérification

Générez un lien unique à envoyer à votre utilisateur. Il ouvre une page de vérification hébergée par VerifyPro Africa.

POSThttps://verifyproafrica.lfdweb.com/api/v1/sessionsCrée une session
GEThttps://verifyproafrica.lfdweb.com/api/v1/sessions?sessionId=xxxStatut d'une session

Créer une session

const { sessionId, verificationUrl, expiresAt } = await fetch('https://verifyproafrica.lfdweb.com/api/v1/sessions', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer vpa_live_xxx', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    type: 'full-kyc',
    documentType: 'national_id',
    redirectUrl: 'https://votre-app.com/verification-done',
    expiresInMinutes: 60,
    prefill: { email: 'client@exemple.com', firstName: 'Kofi' },
    metadata: { userId: 'usr_internal_123', orderId: 'ord_456' }
  })
}).then(r => r.json());

console.log(verificationUrl);
// https://verifyproafrica.lfdweb.com/verify/abc123?token=xyz

Vérifier le statut

const status = await fetch(
  'https://verifyproafrica.lfdweb.com/api/v1/sessions?sessionId=abc123',
  { headers: { 'Authorization': 'Bearer vpa_live_xxx' } }
).then(r => r.json());

// status.status: "pending" | "viewed" | "completed" | "expired"
// status.verificationId: ID de la vérification une fois complétée

Statistiques d'utilisation

GEThttps://verifyproafrica.lfdweb.com/api/v1/usage?period=30Stats d'utilisation
GET https://verifyproafrica.lfdweb.com/api/v1/usage?period=30
Authorization: Bearer vpa_live_xxx

// Réponse
{
  "plan": { "name": "pro", "displayName": "Pro", "verificationsPerMonth": 10000 },
  "currentMonth": { "used": 1234, "limit": 10000, "percentage": 12 },
  "period": {
    "days": 30, "total": 1234, "completed": 1150,
    "failed": 60, "fraud": 24, "averageScore": 88, "successRate": 93
  },
  "typeBreakdown": { "full-kyc": 800, "document": 300, "email": 134 },
  "dailyStats": [
    { "date": "2025-01-01", "verifications": 42, "completed": 40, "failed": 2, "fraud": 0 }
  ]
}

Webhooks

Configurez des URLs qui recevront des notifications HTTP POST signées pour chaque événement.

Événements disponibles

verification.completedVérification réussie
verification.failedVérification échouée
fraud.detectedFraude détectée
quota.warningQuota à 80%
quota.exceededQuota dépassé
document.expiredDocument expiré
session.createdSession créée
plan.expiringAbonnement expirant

Validation de la signature

// Header reçu : X-VerifyPro-Signature: t=1704067200,v1=abc123...
const crypto = require('crypto');

function verifyWebhookSignature(payload, header, secret) {
  const [tsStr, sigStr] = header.split(',');
  const timestamp = tsStr.replace('t=', '');
  const signature = sigStr.replace('v1=', '');
  const signedPayload = `${timestamp}.${payload}`;
  const expected = crypto.createHmac('sha256', secret).update(signedPayload).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'));
}

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const isValid = verifyWebhookSignature(
    req.body.toString(),
    req.headers['x-verifypro-signature'],
    process.env.VERIFYPRO_WEBHOOK_SECRET
  );
  if (!isValid) return res.status(401).send('Signature invalide');

  const event = JSON.parse(req.body);
  switch (event.event) {
    case 'verification.completed':
      await activateUser(event.data.id, event.data.extractedData); break;
    case 'fraud.detected':
      await blockAndAlert(event.data.id); break;
  }
  res.status(200).send('OK');
});

Types de vérification

documentGratuit+

Extraction OCR des données d'un document d'identité. Requis : documentImage, documentType.

extractedData
faceStarter+

Comparaison biométrique entre le document et un selfie. Requis : documentImage, selfieImage.

faceMatch
livenessPro+

Détection de vivacité par analyse de frames vidéo. Requis : videoFrames (min 3).

livenessResult
emailStarter+

Validation de l'email, détection des emails jetables. Requis : email.

emailResult
phoneStarter+

Validation du numéro de téléphone africain. Requis : phone.

phoneResult
amlPro+

Vérification AML/PEP dans les listes de sanctions. Requis : firstName, lastName.

amlResult
full-kycPro+

Combine document + faciale + email + téléphone + AML en une seule requête.

extractedDatafaceMatchemailResultphoneResultamlResult

Codes de réponse HTTP

CodeSignificationAction recommandée
200SuccèsTraiter la réponse normalement
201Ressource crééeRécupérer l'ID de la ressource
400Données invalidesVérifier le corps de la requête
401Clé API invalideVérifier votre clé API
403Permission insuffisanteVérifier les permissions ou upgrader
404Ressource introuvableVérifier l'ID fourni
409ConflitNe pas ré-envoyer
410Ressource expiréeCréer une nouvelle session
429Quota dépasséAttendre ou upgrader
500Erreur serveurRéessayer après quelques secondes

SDKs & Exemples

Node.js / JavaScript

class VerifyProAfrica {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://verifyproafrica.lfdweb.com/api/v1';
  }
  async verify(params) {
    const res = await fetch(`${this.baseUrl}/verify`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' },
      body: JSON.stringify(params)
    });
    if (!res.ok) throw new Error(`API error ${res.status}`);
    return res.json();
  }
  async createSession(params) {
    const res = await fetch(`${this.baseUrl}/sessions`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' },
      body: JSON.stringify(params)
    });
    if (!res.ok) throw new Error(`API error ${res.status}`);
    return res.json();
  }
  async getUsage(period = 30) {
    const res = await fetch(`${this.baseUrl}/usage?period=${period}`, {
      headers: { 'Authorization': `Bearer ${this.apiKey}` }
    });
    return res.json();
  }
}

const client = new VerifyProAfrica(process.env.VERIFYPRO_API_KEY);
const result = await client.verify({
  type: 'full-kyc', documentType: 'national_id',
  documentImage: base64Doc, selfieImage: base64Selfie
});

Python

import requests, base64

class VerifyProAfrica:
    BASE_URL = 'https://verifyproafrica.lfdweb.com/api/v1'
    def __init__(self, api_key: str):
        self.headers = { 'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json' }
    def verify(self, **kwargs) -> dict:
        r = requests.post(f'{self.BASE_URL}/verify', json=kwargs, headers=self.headers, timeout=30)
        r.raise_for_status()
        return r.json()

with open('document.jpg', 'rb') as f:
    doc_b64 = base64.b64encode(f.read()).decode()

client = VerifyProAfrica('vpa_live_xxx')
result = client.verify(type='document', document_type='national_id', document_image=doc_b64, country='BJ')
print(f"Score: {result['overallScore']}/100")

PHP

<?php
class VerifyProAfrica {
    private string $apiKey;
    private string $baseUrl = 'https://verifyproafrica.lfdweb.com/api/v1';
    public function __construct(string $apiKey) { $this->apiKey = $apiKey; }
    public function verify(array $params): array {
        $ch = curl_init($this->baseUrl . '/verify');
        curl_setopt_array($ch, [
            CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->apiKey, 'Content-Type: application/json'],
            CURLOPT_POSTFIELDS => json_encode($params), CURLOPT_TIMEOUT => 30
        ]);
        $response = curl_exec($ch); curl_close($ch);
        return json_decode($response, true);
    }
}

$client = new VerifyProAfrica($_ENV['VERIFYPRO_API_KEY']);
$result = $client->verify(['type' => 'full-kyc', 'documentType' => 'national_id',
    'documentImage' => base64_encode(file_get_contents('document.jpg')), 'email' => 'client@exemple.com']);
echo "Score: " . $result['overallScore'] . "/100\n";

React Native

import { launchCamera, launchImageLibrary } from 'react-native-image-picker';

async function verifyUser() {
  const doc = await launchImageLibrary({ mediaType: 'photo', includeBase64: true });
  const selfie = await launchCamera({ mediaType: 'photo', includeBase64: true });

  const response = await fetch('https://verifyproafrica.lfdweb.com/api/v1/verify', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      type: 'full-kyc', documentType: 'national_id',
      documentImage: 'data:image/jpeg;base64,' + doc.assets[0].base64,
      selfieImage: 'data:image/jpeg;base64,' + selfie.assets[0].base64
    })
  });
  return response.json();
}

Gestion des erreurs

Toutes les erreurs retournent un JSON avec le champ error :

{ "error": "Clé API invalide", "message": "La clé API fournie est invalide ou révoquée.", "status": 401 }

Pattern de retry recommandé

async function verifyWithRetry(params, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const res = await fetch('https://verifyproafrica.lfdweb.com/api/v1/verify', { /* ... */ });
      if (res.status === 429) {
        await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
        continue;
      }
      if (res.status >= 500 && attempt < maxRetries) {
        await new Promise(r => setTimeout(r, 2000 * attempt));
        continue;
      }
      return await res.json();
    } catch (networkError) {
      if (attempt === maxRetries) throw networkError;
      await new Promise(r => setTimeout(r, 1000 * attempt));
    }
  }
}

Sécurité

🔑 Gestion des clés API

  • Stockez vos clés dans des variables d'environnement, jamais en dur dans le code
  • Créez des clés séparées par environnement (dev, staging, production)
  • Donnez le minimum de permissions nécessaires à chaque clé
  • Faites pivoter vos clés régulièrement (tous les 90 jours)
  • Révoquez immédiatement toute clé compromise

🖼 Images et documents

  • Les images sont traitées en mémoire et jamais stockées sur nos serveurs
  • N'envoyez pas des images avec des données PII non nécessaires
  • Compressez les images (JPEG 80%) pour réduire la latence
  • Taille max recommandée : 2 Mo par image

🔒 Transport et chiffrement

  • HTTPS/TLS 1.3 obligatoire pour toutes les requêtes
  • Les webhooks sont signés HMAC-SHA256 — toujours valider la signature
  • Utilisez des timeouts courts (30s max) pour éviter les connexions pendantes

📋 Conformité

  • Respectez le RGPD : informez vos utilisateurs de la collecte de données biométriques
  • Obtenez le consentement explicite avant toute vérification d'identité
  • Conservez un journal de vérification pour vos obligations légales

Prêt à intégrer ?

500 vérifications gratuites pour commencer. Aucune carte bancaire.

Créer un compte gratuit