Intégration KYC – Capture de documents d’identité
1. Démarrage rapide
Copiez ce code, remplacez YOUR_API_KEY par votre clé et ouvrez-le dans un navigateur :
<!DOCTYPE html>
<html>
<head>
<script src="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.js"></script>
<link rel="stylesheet" href="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.css">
</head>
<body>
<roommatik-kyc
mode="full"
api-url="https://kyc.roommatik.com"
api-key="YOUR_API_KEY"
lang="fr"
></roommatik-kyc>
<script>
document.querySelector('roommatik-kyc')
.addEventListener('kyc-complete', (e) => {
if (e.detail.success) {
alert('Document : ' + e.detail.data.documentNumber);
}
});
</script>
</body>
</html>
C’est tout. Lisez la suite pour plus d’options et de détails.
2. Prérequis
Pour utiliser l’une des options d’intégration, vous avez besoin de :
- Clé API : clé d’authentification fournie par Roommatik.
- URL de l’API : adresse de base du service KYC (ex.
https://kyc.roommatik.com). - HTTPS : le composant web nécessite un environnement HTTPS (ou localhost) pour accéder à la caméra.
Contactez votre gestionnaire de compte Roommatik pour obtenir vos identifiants.
3. Options d’intégration
Il existe trois façons d’intégrer la vérification de documents :
| Option | Description | Cas d’utilisation |
|---|---|---|
| A. API directe | Envoyez les images directement à l’API KYC via des requêtes HTTP | Vous disposez déjà de votre propre interface de capture ou pipeline d’images |
| B. Composant – Capture uniquement | Utilisez le composant web pour capturer les images et traitez-les avec votre propre logique | Vous avez besoin de l’interface de capture mais souhaitez contrôler l’envoi à l’API |
| C. Composant – Capture + KYC | Le composant capture les images et les envoie automatiquement à l’API KYC | Intégration complète avec un effort minimal |
4. Option A : API directe
Point de terminaison
POST {API_URL}/api/kyc
En-têtes requis
| En-tête | Valeur | Description |
|---|---|---|
Content-Type | application/json | Type de contenu |
X-Api-Key | Votre clé API | Authentification |
Corps de la requête
{
"image": "IMAGE_BASE64_SANS_PREFIXE",
"returnType": ["Data", "Face"],
"isMappingApplied": true
}
| Champ | Type | Description |
|---|---|---|
image | string | Image encodée en Base64 sans le préfixe data:image/...;base64, |
returnType | string[] | Type de réponse. Toujours ["Data", "Face"] |
isMappingApplied | boolean | Appliquer le mappage des champs. Toujours true |
Réponse réussie (200 OK)
{
"firstName": "JEAN",
"lastName": "DUPONT MARTIN",
"dateOfBirth": "1990-01-15",
"documentNumber": "12345678Z",
"expiryDate": "2030-12-31",
"gender": "M",
"nationality": "FR"
}
Les champs retournés dépendent du type de document et de la nationalité. Les plus courants sont :
| Champ | Description |
|---|---|
firstName | Prénom |
lastName | Nom de famille |
dateOfBirth | Date de naissance |
documentNumber | Numéro de document |
expiryDate | Date d’expiration |
gender | Sexe (M/F) |
nationality | Nationalité (code ISO) |
mrz | Zone de lecture automatique (MRZ) |
Aucune donnée extraite (204 No Content)
Si l’API ne peut pas extraire de données de l’image, elle retourne un code 204 sans corps. Cela indique généralement que l’image est de mauvaise qualité ou ne contient pas de document reconnaissable.
Exemple complet avec cURL
curl -X POST https://kyc.roommatik.com/api/kyc \
-H "Content-Type: application/json" \
-H "X-Api-Key: VOTRE_CLE_API" \
-d '{
"image": "/9j/4AAQSkZJRgABAQ...",
"returnType": ["Data", "Face"],
"isMappingApplied": true
}'
Alternative : Envoyer l’image via une URL présignée
Au lieu du base64, vous pouvez télécharger l’image sur S3 et envoyer une URL présignée :
{
"imageUrl": "https://s3.eu-central-1.amazonaws.com/bucket/key?X-Amz-...",
"returnType": ["Data", "Face"],
"isMappingApplied": true
}
Alternative : Envoyer l’image comme fichier (multipart)
Vous pouvez également envoyer l’image comme fichier en utilisant multipart/form-data :
curl -X POST https://kyc.roommatik.com/api/kyc \ -H "X-Api-Key: VOTRE_CLE_API" \ -F "[email protected]" \ -F "returntype=Data,Face" \ -F "IsMappingApplied=true"
Exemple JavaScript
async function verifyDocument(imageBase64, apiKey) {
// Supprimer le préfixe data:image s'il est présent
const base64 = imageBase64.includes(',')
? imageBase64.split(',')[1]
: imageBase64;
const response = await fetch('https://kyc.roommatik.com/api/kyc', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': apiKey
},
body: JSON.stringify({
image: base64,
returnType: ['Data'],
isMappingApplied: true
})
});
if (response.status === 204) {
throw new Error('Aucune donnée n\'a pu être extraite du document');
}
if (!response.ok) {
throw new Error(`Erreur API : ${response.status}`);
}
return await response.json();
}
5. Option B : Composant web – Capture uniquement
Dans ce mode, le composant fournit l’interface de capture avec détection automatique de documents et retourne les images en Base64 pour que vous les traitiez avec votre propre logique.
Installation
Ajoutez les balises suivantes dans le <head> de votre page HTML :
<script src="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.js"></script> <link rel="stylesheet" href="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.css">
Utilisation
<roommatik-kyc
mode="capture-only"
lang="fr"
></roommatik-kyc>
<script>
const kyc = document.querySelector('roommatik-kyc');
kyc.addEventListener('kyc-captured', (e) => {
const { frontImage, backImage } = e.detail;
console.log('Recto :', frontImage); // data:image/jpeg;base64,...
console.log('Verso :', backImage); // data:image/jpeg;base64,... ou null
// Envoyez les images à votre backend ou traitez-les ici
});
kyc.addEventListener('kyc-error', (e) => {
console.error('Erreur :', e.detail.message);
});
kyc.addEventListener('kyc-cancel', () => {
console.log('L\'utilisateur a annulé la capture');
});
</script>
combine-images est activé, l’événement kyc-captured renvoie { combinedImage } au lieu de { frontImage, backImage }. L’image combinée contient les deux faces empilées verticalement.6. Option C : Composant web – Capture + KYC
Dans ce mode, le composant capture les images et les envoie automatiquement à l’API KYC. Vous recevez directement les données extraites du document.
Installation
Ajoutez les balises suivantes dans le <head> de votre page HTML (si elles ne sont pas déjà incluses) :
<script src="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.js"></script> <link rel="stylesheet" href="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.css">
Utilisation
<roommatik-kyc
mode="full"
api-url="https://kyc.roommatik.com"
api-key="VOTRE_CLE_API"
lang="fr"
<!-- combine-images: combine recto et verso en une seule image -->
></roommatik-kyc>
<script>
const kyc = document.querySelector('roommatik-kyc');
kyc.addEventListener('kyc-complete', (e) => {
if (e.detail.success) {
console.log('Données extraites :', e.detail.data);
// { firstName, lastName, dateOfBirth, documentNumber, ... }
} else {
console.error('Erreur :', e.detail.error);
}
});
kyc.addEventListener('kyc-error', (e) => {
console.error('Erreur :', e.detail.message);
});
</script>
7. Référence du composant
Attributs du Web Component
| Attribut | Type | Par défaut | Description |
|---|---|---|---|
mode | "capture-only" | "full" | "capture-only" | Mode de fonctionnement |
api-url | string | — | URL de base de l’API KYC (obligatoire en mode full) |
api-key | string | — | Clé API (obligatoire en mode full) |
lang | string | "en" | Langue : en, es, fr, de, it, pt |
primary-color | string (hex) | #3b82f6 | Couleur principale de l’interface |
two-sided | boolean | true | Scanner deux faces (recto + verso). Mettre à false pour les documents à une seule face (ex. passeport) |
max-image-width | number | 800 | Largeur maximale de l’image capturée (px) |
jpeg-quality | number | 0.70 | Qualité JPEG (0 à 1) |
auto-start | boolean | true | Démarrer la caméra automatiquement au montage |
combine-images | boolean | false | Si true, les images recto et verso sont combinées en une seule image et envoyées en un seul appel API |
labels | JSON string | — | Textes personnalisés (remplacent les traductions intégrées) |
Événements
| Événement | Mode | Détail (e.detail) |
|---|---|---|
kyc-captured | capture-only | { frontImage: string, backImage: string | null, combinedImage: string | null } |
kyc-complete | full | { success: boolean, data?: object, error?: string, rawResponse?: object } |
kyc-error | les deux | objet Error |
kyc-cancel | les deux | — |
8. Faces du document
Utilisez l’attribut two-sided pour indiquer si le document a une ou deux faces :
two-sided | Comportement | Exemple |
|---|---|---|
true (par défaut) | Scanne recto + verso | Carte d’identité, titre de séjour |
false | Scanne une seule face | Passeport |
9. Gestion des erreurs
Codes de réponse de l’API
| Code | Signification |
|---|---|
200 | Données extraites avec succès |
204 | Aucune donnée extraite (image de mauvaise qualité ou document non reconnu) |
400 | Requête incorrecte (paramètres invalides) |
401 | Non autorisé (clé API invalide ou manquante) |
403 | Interdit (compte bloqué, licence expirée, IP non autorisée ou limite de requêtes dépassée) |
429 | Trop de requêtes (limite de débit dépassée) |
500 | Erreur interne du serveur |
Messages d’erreur courants
| Message | Cause |
|---|---|
License Expired | Votre licence a expiré. Contactez votre administrateur. |
License Blocked | Votre licence a été bloquée. |
Account is Blocked | Le compte est bloqué. |
Access forbidden. Your IP is not whitelisted. | Votre IP n’est pas dans la liste blanche. |
Rate limit exceeded | Vous avez dépassé la limite de requêtes par minute ou par jour. |
No data could be extracted from the document | L’image ne contient pas de document reconnaissable ou est de mauvaise qualité. |
10. Limites et restrictions
| Concept | Détails |
|---|---|
| Limitation de débit | Configurable par compte (par minute et par jour) |
| Délai d’attente | 30 secondes par défaut |
| Format d’image | JPEG ou PNG (Base64, URL présignée ou téléchargement de fichier multipart) |
| HTTPS obligatoire | Le composant web nécessite HTTPS pour accéder à la caméra |
| Navigateurs compatibles | Chrome, Firefox, Safari, Edge (versions récentes) |
| Taille maximale d’image | Recommandé en dessous de 2 Mo par image. Les images plus grandes peuvent provoquer des timeouts. |
11. Exemple complet d’intégration
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vérification de document</title>
<script src="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.js"></script>
<link rel="stylesheet" href="https://sdk.roommatik.com/kyc/v1/roommatik-kyc.css">
</head>
<body>
<h1>Vérification d'identité</h1>
<div id="result"></div>
<roommatik-kyc
mode="full"
api-url="https://kyc.roommatik.com"
api-key="VOTRE_CLE_API"
lang="fr"
primary-color="#1a73e8"
></roommatik-kyc>
<script>
const kyc = document.querySelector('roommatik-kyc');
const resultDiv = document.getElementById('result');
kyc.addEventListener('kyc-complete', (e) => {
if (e.detail.success) {
const d = e.detail.data;
resultDiv.innerHTML = `
<h2>Document vérifié</h2>
<p><strong>Nom :</strong> ${d.firstName} ${d.lastName}</p>
<p><strong>Document :</strong> ${d.documentNumber}</p>
<p><strong>Expiration :</strong> ${d.expiryDate}</p>
`;
} else {
resultDiv.innerHTML = `<p style="color:red">Erreur : ${e.detail.error}</p>`;
}
});
kyc.addEventListener('kyc-error', (e) => {
resultDiv.innerHTML = `<p style="color:red">Erreur : ${e.detail.message}</p>`;
});
</script>
</body>
</html>
11. Choisir le bon returnType
| returnType | Cas d’utilisation | Réponse |
|---|---|---|
["Data"] | OCR uniquement — option la plus rapide. À utiliser quand vous n’avez besoin que des champs texte extraits (nom, numéro de document, dates, etc.). | Petit JSON avec uniquement des champs texte. |
["Data", "Face"] | OCR + photo faciale. Nécessaire si vous prévoyez d’utiliser face_vector pour la comparaison biométrique. | JSON + image faciale en base64 (~30-50 Ko suppl.). |
["Data", "Face", "Signature"] | Extraction complète. Renvoie les champs texte, la photo faciale et l’image de la signature. | JSON + deux images en base64. |
Pour la plupart des intégrations qui n’ont besoin que de l’extraction de données du document (check-in, inscription, vérification d’identité sans biométrie), utilisez
returnType: ["Data"] avec isMappingApplied: true. C’est la configuration la plus rapide et la plus légère : l’API ignore l’extraction du visage et de la signature, renvoie une réponse plus petite et fournit des noms de champs normalisés (firstName, lastName, documentNumber, etc.) prêts à l’emploi.13. Embedding facial (Face Vector)
Lorsque l’image d’un document contient une photographie (carte d’identité, passeport, etc.), l’API peut extraire un vecteur d’embedding facial à 512 dimensions. Ce vecteur est une représentation numérique du visage qui permet :
- Comparaison faciale : comparer la photo du document avec un selfie en temps réel.
- Dédoublonnage : détecter si deux documents appartiennent à la même personne.
- Vérification d’identité : stocker le vecteur et le comparer avec de futures soumissions.
Comment le demander
Ajoutez face_vector: true au corps de la requête :
{
"image": "IMAGE_BASE64_SANS_PREFIXE",
"returnType": ["Data", "Face"],
"isMappingApplied": true,
"face_vector": true
}
Avec multipart/form-data :
curl -X POST https://kyc.roommatik.com/api/kyc \
-H "X-Api-Key: VOTRE_API_KEY" \
-F "[email protected]" \
-F "returntype=Data,Face" \
-F "IsMappingApplied=true" \
-F "face_vector=true"
Important : returnType doit inclure "Face". Sans cette valeur, l’API n’extraira pas la photographie faciale et FaceVector sera toujours null.
Réponse
Lorsque face_vector est activé et qu’un visage est détecté, la réponse inclut un champ supplémentaire FaceVector :
{
"firstName": "JEAN",
"lastName": "DUPONT",
"documentNumber": "12345678Z",
"FaceVector": [0.0234, -0.0891, 0.0412, "... (512 floats)"]
}
| Champ | Type | Description |
|---|---|---|
FaceVector | number[] | Tableau de 512 valeurs float (embedding ArcFace). Normalisé L2. Présent uniquement lorsque face_vector=true et qu’un visage est détecté. |
Visage non détecté : si aucun visage n’est trouvé dans l’image, FaceVector sera null.
Comparaison de vecteurs faciaux
Les vecteurs sont comparés par similarité cosinus. Un score supérieur à 0,5 indique généralement la même personne :
function cosineSimilarity(a, b) {
let dot = 0, normA = 0, normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}
const similarite = cosineSimilarity(vecteurDocument, vecteurSelfie);
if (similarite > 0.5) {
console.log('Correspondance faciale confirmee');
}
14. Décodage QR miDNI
La carte d’identité nationale espagnole (DNI) contient un code QR lisible via l’application miDNI. Ce QR encode les données personnelles du titulaire avec une signature numérique pour vérifier l’authenticité.
Endpoint
POST {API_URL}/api/qr/midni
Requête
Envoyez le payload QR en Base64 ou hexadécimal :
{
"Base64Data": "PAYLOAD_QR_EN_BASE64"
}
Ou :
{
"HexData": "PAYLOAD_QR_EN_HEXADECIMAL"
}
Note : cet endpoint attend les données binaires brutes du code QR, pas une image du QR. Utilisez une bibliothèque de scan QR pour extraire le payload.
Authentification
| Méthode | En-tête |
|---|---|
| API Key | X-Api-Key: VOTRE_API_KEY |
| Bearer token | Authorization: Bearer TOKEN |
Réponse (200 OK)
{
"data": {
"documentNumber": "12345678Z",
"firstName": "NOM",
"lastName": "PRENOM1 PRENOM2",
"dateOfBirth": "01/01/1990",
"gender": "M",
"nationality": "ESP",
"expiryDate": "31/12/2030",
"signatureValid": "true",
"dataExpired": "false"
},
"responseTime": 12,
"description": "miDNI QR (VDS) - Verification: Valid"
}
Champs de la réponse
| Champ | Description |
|---|---|
documentNumber | Numéro du DNI |
firstName | Prénom(s) |
lastName | Noms de famille complets |
dateOfBirth | Date de naissance |
gender | Sexe (M/F) |
nationality | Nationalité (code ISO) |
expiryDate | Date d’expiration du document |
address | Adresse complète |
signatureValid | Si la signature numérique du QR est valide |
dataExpired | Si les données du QR ont expiré |
Codes d’erreur
| Code | Signification |
|---|---|
| 400 | Format de données invalide, QR expiré ou signature invalide |
| 401 | Non autorisé (clé API incorrecte) |
| 402 | Crédits insuffisants |
| 500 | Erreur interne du serveur |
