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://verifypro-africa.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 verifypro-africa.com et créez votre première clé API depuis le dashboard.
Lancez votre première vérification
curl -X POST https://verifypro-africa.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://verifypro-africa.com/api/v1/verifyParamètres du corps (JSON)
| Champ | Type | Requis | Description |
|---|---|---|---|
| type | string | ✅ | Type de vérification (voir section Types) |
| documentType | string | Conditionnel | national_id, passport, driving_license, residence_permit |
| documentImage | string | Conditionnel | Image base64 du document (JPG/PNG, max 10 Mo) |
| selfieImage | string | Conditionnel | Selfie base64 pour la comparaison faciale |
| videoFrames | string[] | Conditionnel | Frames vidéo base64 pour la détection de vivacité |
| string | Conditionnel | Email à vérifier | |
| phone | string | Conditionnel | 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://verifypro-africa.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, // string base64
selfieImage: selfieBase64, // string base64
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, sans aucune intégration frontend supplémentaire.
https://verifypro-africa.com/api/v1/sessionshttps://verifypro-africa.com/api/v1/sessions?sessionId=xxxCréer une session
// Créer un lien de vérification pour votre utilisateur
const { sessionId, verificationUrl, expiresAt } = await fetch('https://verifypro-africa.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());
// Envoyer verificationUrl à votre utilisateur par email ou SMS
// Exemple : https://verifypro-africa.com/verify/abc123?token=xyz
console.log(verificationUrl);Vérifier le statut
const status = await fetch(
'https://verifypro-africa.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://verifypro-africa.com/api/v1/usage?period=30GET https://verifypro-africa.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
// Chaque requête webhook contient ce header :
// 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');
// Utiliser un comparateur sécurisé pour éviter les timing attacks
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
}
// Express.js
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':
// Activer le compte utilisateur
await activateUser(event.data.id, event.data.extractedData);
break;
case 'fraud.detected':
// Bloquer et alerter
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 ou manquante | Vérifier votre clé API |
| 403 | Permission insuffisante | Vérifier les permissions de la clé ou upgrader |
| 404 | Ressource introuvable | Vérifier l'ID fourni |
| 409 | Conflit (ex: session déjà complétée) | Ne pas ré-envoyer |
| 410 | Ressource expirée | Créer une nouvelle session |
| 429 | Quota dépassé ou rate limit | Attendre ou upgrader votre plan |
| 500 | Erreur serveur | Réessayer après quelques secondes |
SDKs & Exemples
Node.js / JavaScript
// Installation (pas encore de package npm officiel)
// Utilisez fetch ou axios directement
class VerifyProAfrica {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://verifypro-africa.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();
}
}
// Utilisation
const client = new VerifyProAfrica(process.env.VERIFYPRO_API_KEY);
const result = await client.verify({
type: 'full-kyc',
documentType: 'national_id',
documentImage: base64Doc,
selfieImage: base64Selfie,
email: 'user@example.com'
});Python
import requests
import base64
class VerifyProAfrica:
BASE_URL = 'https://verifypro-africa.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:
response = requests.post(
f'{self.BASE_URL}/verify',
json=kwargs,
headers=self.headers,
timeout=30
)
response.raise_for_status()
return response.json()
def create_session(self, **kwargs) -> dict:
response = requests.post(
f'{self.BASE_URL}/sessions',
json=kwargs,
headers=self.headers
)
response.raise_for_status()
return response.json()
# Utilisation
with open('document.jpg', 'rb') as f:
doc_b64 = base64.b64encode(f.read()).decode()
client = VerifyProAfrica(api_key='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://verifypro-africa.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);
}
}
// Utilisation
$client = new VerifyProAfrica($_ENV['VERIFYPRO_API_KEY']);
$docBase64 = base64_encode(file_get_contents('document.jpg'));
$result = $client->verify([
'type' => 'full-kyc',
'documentType' => 'national_id',
'documentImage' => $docBase64,
'email' => 'client@exemple.com'
]);
echo "Score: " . $result['overallScore'] . "/100\n";Intégration React Native (Mobile)
import { launchImageLibrary, launchCamera } from 'react-native-image-picker';
import RNFS from 'react-native-fs';
async function verifyUser() {
// 1. Sélectionner le document
const docResult = await launchImageLibrary({ mediaType: 'photo', includeBase64: true });
const docBase64 = docResult.assets[0].base64;
// 2. Prendre le selfie
const selfieResult = await launchCamera({ mediaType: 'photo', includeBase64: true });
const selfieBase64 = selfieResult.assets[0].base64;
// 3. Envoyer à VerifyPro Africa
const response = await fetch('https://verifypro-africa.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,' + docBase64,
selfieImage: 'data:image/jpeg;base64,' + selfieBase64
})
});
const result = await response.json();
return result; // { status, overallScore, riskLevel, extractedData, ... }
}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://verifypro-africa.com/api/v1/verify', { /* ... */ });
if (res.status === 429) {
// Rate limit — attendre et réessayer
const delay = Math.pow(2, attempt) * 1000;
await new Promise(r => setTimeout(r, delay));
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