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.
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.
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"
}'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é
https://verifyproafrica.lfdweb.com/api/v1/verifyLance une vérificationParamètres du corps (JSON)
| Champ | Type | Requis | Description |
|---|---|---|---|
| type | string | ✅ | Type de vérification (voir section Types) |
| documentType | string | Cond. | national_id, passport, driving_license, residence_permit |
| documentImage | string | Cond. | Image base64 du document (JPG/PNG, max 10 Mo) |
| selfieImage | string | Cond. | Selfie base64 pour la comparaison faciale |
| videoFrames | string[] | Cond. | Frames vidéo base64 pour la détection de vivacité |
| string | Cond. | Email à vérifier | |
| phone | string | Cond. | Numéro de téléphone avec indicatif (+229...) |
| firstName | string | ❌ | Prénom pour la vérification AML |
| lastName | string | ❌ | Nom pour la vérification AML |
| country | string | ❌ | Code 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); // falseRé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.
https://verifyproafrica.lfdweb.com/api/v1/sessionsCrée une sessionhttps://verifyproafrica.lfdweb.com/api/v1/sessions?sessionId=xxxStatut d'une sessionCré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=xyzVé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éeStatistiques d'utilisation
https://verifyproafrica.lfdweb.com/api/v1/usage?period=30Stats d'utilisationGET 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éussieverification.failedVérification échouéefraud.detectedFraude détectéequota.warningQuota à 80%quota.exceededQuota dépassédocument.expiredDocument expirésession.createdSession crééeplan.expiringAbonnement expirantValidation 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.
faceStarter+Comparaison biométrique entre le document et un selfie. Requis : documentImage, selfieImage.
livenessPro+Détection de vivacité par analyse de frames vidéo. Requis : videoFrames (min 3).
emailStarter+Validation de l'email, détection des emails jetables. Requis : email.
phoneStarter+Validation du numéro de téléphone africain. Requis : phone.
amlPro+Vérification AML/PEP dans les listes de sanctions. Requis : firstName, lastName.
full-kycPro+Combine document + faciale + email + téléphone + AML en une seule requête.
Codes de réponse HTTP
| Code | Signification | Action recommandée |
|---|---|---|
| 200 | Succès | Traiter la réponse normalement |
| 201 | Ressource créée | Récupérer l'ID de la ressource |
| 400 | Données invalides | Vérifier le corps de la requête |
| 401 | Clé API invalide | Vérifier votre clé API |
| 403 | Permission insuffisante | Vérifier les permissions ou upgrader |
| 404 | Ressource introuvable | Vérifier l'ID fourni |
| 409 | Conflit | Ne pas ré-envoyer |
| 410 | Ressource expirée | Créer une nouvelle session |
| 429 | Quota dépassé | Attendre ou upgrader |
| 500 | Erreur serveur | Ré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