Webhooks đź””
Configurez une URL de webhook pour recevoir les événements en temps réel.
Événements​
verification.createdverification.processingverification.completedverification.failedverification.needs_review
En-têtes de sécurité​
X-Signature: signature HMAC-SHA256X-Timestamp: epoch seconds
La signature est calculée sur la base de: payload_to_sign = X-Timestamp + '.' + raw_body. Puis:
signature = hex(hmac_sha256(webhook_secret, payload_to_sign)).
Exemple de payload​
{
"id": "evt_01HYY...",
"type": "verification.completed",
"created_at": "2025-08-09T10:23:10Z",
"data": {
"verification_id": "ver_01HXX...",
"status": "completed",
"result": {
"passed": true,
"face_match": {"score": 0.93, "threshold": 0.85, "passed": true},
"ocr": {
"national_id": {"first_name": "AWA", "last_name": "TRAORE", "id_number": "AB12345"}
},
"checks": {"watchlists": {"passed": true}}
}
}
}
Vérifier la signature​
Node.js:
import crypto from 'crypto';
function verifySignature(rawBody, timestamp, signature, secret) {
const payloadToSign = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac('sha256', secret)
.update(payloadToSign, 'utf8')
.digest('hex');
const safeEqual = crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(signature, 'hex')
);
const skew = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
return safeEqual && skew <= 300; // 5 minutes de tolérance
}
Python:
import hmac, hashlib, time
def verify_signature(raw_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
payload = f"{timestamp}.{raw_body.decode('utf-8')}".encode('utf-8')
expected = hmac.new(secret.encode('utf-8'), payload, hashlib.sha256).hexdigest()
skew = abs(int(time.time()) - int(timestamp))
return hmac.compare_digest(expected, signature) and skew <= 300
Champs et types​
- En-tĂŞtes HTTP:
X-Timestamp(string, obligatoire): horodatage Unix (secondes)X-Signature(string hex, obligatoire): HMAC-SHA256 du payload signéContent-Type(string, obligatoire):application/json
- Payload JSON:
id(string, obligatoire): identifiant d’événement uniquetype(string, obligatoire): type d’événementcreated_at(ISO8601, obligatoire): date de créationdata(objet, obligatoire): contenu spécifique à l’événementverification_id(string, obligatoire)status(enum, obligatoire):created|processing|completed|failed|needs_reviewresult(objet, optionnel selon type): scores, OCR, checks
Réponses et retries​
- Répondez
2xxdans les 10s ✅ - En cas d’échec, nous réessaierons avec backoff exponentiel jusqu’à 24h
- Les événements sont idempotents via
id(dédupliquez côté client)
Configuration​
- Définissez
webhook_urletwebhook_secretau niveau du compte - Vous pouvez surcharger
webhook_urlpar requête (voir création de vérification)