Authentification
L'API Conformitiel utilise un token Bearer par cabinet. Chaque token est scopé à une organization unique et à un rôle applicatif.
Créer un token
- Connectez-vous à l'application (rôle admin ou dirigeant).
- Rendez-vous dans
/parametres/api-tokens. - Cliquez sur "Générer un nouveau token" — libellé, rôle, expiration.
- Copiez le token immédiatement — il n'est jamais réaffiché (seul le SHA-256 est stocké côté serveur).
Format du token : cft_<32 caractères base64url>. Le préfixe permet de le détecter en clair dans les logs (et d'alerter en cas de leak).
Utilisation dans une requête
curl -X GET https://conformitiel.fr/api/fiches-vigilance \
-H "Authorization: Bearer cft_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Le middleware valide le préfixe côté Edge (rapide) et la signature complète côté route (Node runtime). Un token expiré ou révoqué → 401.
Votre premier criblage (personne physique)
Criblez une personne physique contre les 6 registres de sanctions et PPE en un appel synchrone (< 2 secondes).
curl -X POST https://conformitiel.fr/api/screening \
-H "Authorization: Bearer cft_xxx..." \
-H "Content-Type: application/json" \
-d '{
"nom": "DUPONT",
"prenom": "Jean",
"dateNaissance": "1975-03-14",
"nationalite": "FR"
}'Réponse
{
"person": { "nom": "DUPONT", "prenom": "Jean", ... },
"results": [
{
"source": "Gels Avoirs (DG Trésor)",
"type": "sanctions",
"hit": false,
"score": null,
"alertId": "9f3e4c2a-..."
},
{
"source": "OpenSanctions",
"type": "sanctions",
"hit": false,
"score": 0.72,
"matchedName": "DUPONT Jean-Marc",
"alertId": "5a1d2b8f-..."
},
// ... 4 autres sources
],
"summary": {
"totalChecks": 6,
"hits": 0,
"nearMatches": 1,
"clean": 5,
"errors": 0
}
}Chaque résultat contient un alertId persistant en base. Utilisez-le pour qualifier l'alerte (faux positif, confirmé, escaladé) via PATCH /api/screening/alerts/[id]/status.
Audit SIREN complet (personne morale)
Un audit SIREN interroge INSEE + INPI RBE + BODACC + les 6 registres de sanctions pour chaque personne (dirigeants + BE identifiés). Réponse en SSE streaming (5-30s selon volume).
curl -N "https://conformitiel.fr/api/audit?sirens=552032534" \
-H "Authorization: Bearer cft_xxx..." \
-H "Accept: text/event-stream"
# Plusieurs SIREN : ?sirens=552032534,542107651Events SSE reçus
event: step
data: { "step_id": "insee", "status": "running", "details": "…" }
event: step
data: { "step_id": "insee", "status": "completed" }
// ... sanctions, inpi, bodacc, screening, scoring
event: entity_complete
data: { "siren": "552032534", … }
event: complete
data: {
"totalProcessed": 1,
"results": {
"siren": "552032534", "company_name": "DANONE",
"risk_level": "MOYEN", "risk_score": 32, "date": "2026-09-10T…",
"identite": { … }, "beneficiaires": [ … ], "dirigeants": [ … ]
}
}
event: error
data: { "message": "…" }Sans SSE : POST /api/audit-batches (voir « Audit batch ») puis lecture des résultats via GET /api/history/[siren]. Le webhook audit.completed est émis dans les deux cas.
Créer et gérer des fiches vigilance
Les fiches vigilance sont la documentation KYC persistante exigée par Art. L.561-5 CMF.
# Créer une fiche personne morale
POST /api/fiches-vigilance
{
"typeClient": "PERSONNE_MORALE",
"denomination": "DANONE",
"siren": "552032534",
"identification": { ... },
"beneficiairesEffectifs": [ ... ],
"evaluationRisque": { ... }
}
# Valider la fiche — pour une étude notariale, valider = signer
PUT /api/fiches-vigilance/[id]
{ "action": "validate", "commentaire": "..." }
→ fiche + signedVersion { versionNumber, hash } (signature simple eIDAS art. 25.1 scellée dans la version)
# Signer a posteriori une fiche déjà validée (notariat)
PUT /api/fiches-vigilance/[id]
{ "action": "sign" }
# Générer le PDF opposable (sceau vérifiable en pied de page + cachet QR)
GET /api/fiches-vigilance/[id]/pdf
→ application/pdf (auto-archivé S3 Object Lock 5 ans)
# PDF d'une version immuable (sceau déterministe U + hash de version)
GET /api/fiches-vigilance/[id]/versions/[n]/pdf
# Lister les fiches
GET /api/fiches-vigilance?statut=VALIDEE&niveauRisque=ELEVE
# Détecter les doublons
GET /api/fiches-vigilance/duplicates
→ { clusters: [...], totalClusters, totalFichesInvolved }
# Fusionner deux fiches doublons
POST /api/fiches-vigilance/merge
{ "targetFicheId": "...", "sourceFicheIds": [...], "mergeReason": "..." }Documents signés et sceau vérifiable
Chaque PDF émis par Conformitiel porte un sceau vérifiable : un code de 12 caractères en pied de page (« Sceau XXXX-XXXX-XXXX ») et un cachet QR en dernière page. L'empreinte SHA-256 du fichier servi est enregistrée côté plateforme ; un tiers (contrôleur, client, confrère) peut vérifier un document reçu sans compte sur conformitiel.fr/v/<code> — l'empreinte du fichier déposé est calculée dans le navigateur, jamais transmise.
# Vérification publique d'un sceau (aucune authentification, 30 req/min/IP)
GET /api/v/7KQ2M9XZ4PLD
→ { valid: true, documentType, documentLabel, orgName, generatedAt,
sha256, rfc3161: { present, verified }, archived, version? }
→ 404 { valid: false, reason: "unknown" } si le code n'existe pas
# Les livrables signés (signature électronique simple, eIDAS art. 25.1)
GET /api/report/pdf?siren=552032534 # rapport d'audit PDF signé (livrable officiel)
GET /api/report/package?sirens=552032534 # ZIP : PDF signé + .sha256 + jeton RFC 3161 + journal API + Word de travail
POST /api/dossier-lcbft { dateDebut, dateFin, format: "pdf" }
# dossier de conformité consolidé : pièces + annexes
# + attestation signée du responsable LCB-FT
POST /api/screening/pdf # rapport de criblage (annexe adverse media incluse)
GET /api/fiches-vigilance/[id]/synthese-vigilance
GET /api/audit/[id]/synthese-vigilance # synthèses 1 page scelléesCe que contient une signature
Nom, email et rôle du signataire, horodatage, méthode (session authentifiée avec mention du deuxième facteur TOTP s'il est actif, ou jeton API avec le nom et le préfixe du jeton cft_ utilisé), adresse IP, texte de consentement affiché au moment du clic ou accepté par l'appel API. La signature est scellée par l'empreinte SHA-256 du document, l'archivage S3 immuable (Object Lock 5 ans) et le sceau vérifiable ; pour une fiche notariale, elle est embarquée dans la version avant le calcul du hash de chaîne et l'horodatage RFC 3161.
Niveau : signature électronique simple conforme au règlement eIDAS (UE) 910/2014, art. 25.1, recevable en justice (C. civ. art. 1367). Le signataire est l'utilisateur porteur du token ou de la session qui déclenche la génération. Une signature produite via API est tracée comme telle dans le PDF (« via jeton API « Prod » (cft_xxxxxxxx…) ») et dans le journal de contrôle du cabinet (authMethod, apiTokenId).
Ces endpoints exigent un jeton cft_ du cabinet concerné. Un jeton partenaire cfp_ est refusé (401) : voir « Isolation stricte v1 » plus bas.
Import batch (CSV/XLSX)
Créez en masse des fiches de vigilance + lancez le criblage automatique en uploadant un fichier CSV ou XLSX. Limite : 30 Mo, 10 000 lignes par batch. L'audit SIREN reste séparé (voir section suivante) pour éviter la brûlure quota.
Workflow en 4 étapes
- Upload multipart → détection colonnes + mapping auto
- Enregistrement du mapping user + consentement RGPD → validation
- Lancement du worker en fire-and-forget
- Polling status + récupération rapport CSV
1. Upload
curl -X POST https://conformitiel.fr/api/imports \
-H "Authorization: Bearer cft_..." \
-F "file=@clients.xlsx"
# Réponse
{
"batchId": "batch_abc123",
"columns": ["Nom", "Prénom", "SIREN", "Email", ...],
"autoMapping": {
"nom": "Nom",
"prenom": "Prénom",
"siren": "SIREN",
"email": "Email"
},
"totalRows": 487,
"format": "xlsx"
}2. Valider le mapping
curl -X POST https://conformitiel.fr/api/imports/batch_abc123/mapping \
-H "Authorization: Bearer cft_..." \
-H "Content-Type: application/json" \
-d '{
"columnMapping": {
"nom": "Nom",
"prenom": "Prénom",
"siren": "SIREN",
"email": "Email"
},
"actionsRequested": {
"createFiches": true,
"runScreening": true
},
"rgpdConsent": true
}'
# Réponse
{
"success": true,
"validCount": 480,
"invalidCount": 7,
"estimatedCost": 480
}3. Lancer le traitement
curl -X POST https://conformitiel.fr/api/imports/batch_abc123/execute \
-H "Authorization: Bearer cft_..."
# Réponse immédiate (fire-and-forget côté serveur)
{ "success": true, "batchId": "batch_abc123" }4. Suivre la progression
curl https://conformitiel.fr/api/imports/batch_abc123/progress \
-H "Authorization: Bearer cft_..."
# Réponse
{
"status": "processing",
"progress": {
"total": 487,
"pending": 200,
"success": 280,
"error": 5,
"skipped": 2,
"quotaExceeded": 0
},
"startedAt": "2026-08-25T14:32:11.000Z"
}5. Rapport final CSV
curl https://conformitiel.fr/api/imports/batch_abc123/report \
-H "Authorization: Bearer cft_..." \
-o rapport.csv
# CSV avec : rowIndex, status, message, createdFicheId,
# isDuplicate, duplicateOfFicheId + toutes les colonnes originales.
# BOM UTF-8 + séparateur ; pour compatibilité Excel FR.Résilience
- Détection doublons : SIREN pour PM, nom+prenom pour PP. Les doublons sont marqués
skippedavec référence à la fiche existante. - Guard quota strict : dès que le quota mensuel est atteint, les lignes restantes sont marquées
quota_exceededsans dépassement silencieux. - Watchdog : un batch bloqué > 15 min sans progression est marqué
failedpar un cron. - Reprise :
POST /api/imports/[batchId]/retryrelance uniquement les lignes non-success, préserve les fiches déjà créées. - Annulation :
DELETE /api/imports/[batchId]— le worker check toutes les 10 lignes et s'arrête proprement. - Webhook :
import_batch.completedouimport_batch.faileddispatch à la fin. Voir section Webhooks.
Champs supportés (mapping)
typePersonne (PP/PM auto-détecté si SIREN présent), nom, prenom, denomination, siren, dateNaissance (ISO / FR / Excel serial), lieuNaissance, nationalite, email, telephone, adresse, codePostal, ville, pays.
Audit SIREN en masse
Lancez un audit SIREN sur un lot de personnes morales — typiquement après un import batch pour compléter les fiches créées avec les données INSEE / INPI RBE / BODACC. Rate-limité à 2 audits concurrents (INSEE) + dédup 7 jours (si un audit récent existe pour un SIREN, il est réutilisé sans consommer le quota).
Lancer un batch
curl -X POST https://conformitiel.fr/api/audit-batches \
-H "Authorization: Bearer cft_..." \
-H "Content-Type: application/json" \
-d '{
"sirens": ["123456789", "987654321", "456789123"],
"sourceImportBatchId": "batch_abc123"
}'
# Réponse
{
"batchId": "aubatch_xyz789",
"totalCount": 3
}Suivre / annuler
# Progression
GET /api/audit-batches/aubatch_xyz789/progress
# Detail complet (items + statut par SIREN)
GET /api/audit-batches/aubatch_xyz789
# Annuler
DELETE /api/audit-batches/aubatch_xyz789Note : les audits batch produisent un scoring batch-1.0 minimal (sans criblage exhaustif des dirigeants). Pour un scoring complet + criblage PPE/sanctions par dirigeant, lancer un audit unitaire via l'interface cabinet sur les SIREN suspects.
Webhook
Événement audit.completed dispatch en fin de batch avec les compteurs.
Surveillance continue
Art. L.561-6 CMF impose une vigilance constante sur les clients (revue annuelle en simplifié, semestrielle en standard, trimestrielle en renforcé). L'API expose la configuration et le suivi des recriblages automatiques programmés pour chaque personne surveillée.
À la validation d'une fiche vigilance, l'app auto-provisionne un recriblage récurrent pour le client + chaque BE identifié, avec une fréquence dérivée de fiche.frequenceRevue. Le worker cron tourne toutes les 6h, respecte le quota mensuel du plan et les rate-limits publics des sources externes (INSEE 5/s, INPI 3/s, BODACC 5/s, OpenSanctions 8/s — marge 30% sous les limites documentées).
Lister les recriblages
curl https://conformitiel.fr/api/recurring-screenings \
-H "Authorization: Bearer cft_..."
# Réponse
{
"items": [
{
"id": "rec_...",
"ficheVigilanceId": "fic_...",
"personNom": "DUPONT", "personPrenom": "Marie",
"personType": "PP",
"frequency": "annual",
"enabled": true,
"lastRunAt": "2026-08-15T09:00:00.000Z",
"lastRunHits": 0,
"nextRunAt": "2027-08-15T09:00:00.000Z",
"totalRunsCount": 3,
"totalNewHitsCount": 0,
"ficheDenomination": "DUPONT Marie",
"ficheNiveauRisque": "MOYEN"
}
],
"stats": {
"total": 47,
"dueNow": 3,
"dueSoon": 12,
"totalHits": 2,
"totalRuns": 156
}
}
# Filtres :
GET /api/recurring-screenings?onlyDue=1 # uniquement dus maintenant
GET /api/recurring-screenings?onlyEnabled=0 # inclut aussi les pausedCréer un recriblage manuel
Utile pour surveiller une personne hors du flux fiche vigilance standard (ex : intermédiaire commercial, contrepartie occasionnelle).
curl -X POST https://conformitiel.fr/api/recurring-screenings \
-H "Authorization: Bearer cft_..." \
-H "Content-Type: application/json" \
-d '{
"ficheVigilanceId": "fic_...",
"personNom": "MARTIN",
"personPrenom": "Jean",
"personNationalite": "FR",
"personType": "PP",
"frequency": "quarterly"
}'
# Fréquences supportées : daily, weekly, monthly, quarterly, biannual, annualAjuster / pauser / supprimer
# Changer la fréquence (recalcule nextRunAt)
PATCH /api/recurring-screenings/[id]
Body: { "frequency": "monthly" }
# Pauser (ne sera plus rejoué par le cron)
POST /api/recurring-screenings/[id]/toggle
Body: { "enabled": false }
# Supprimer définitivement
DELETE /api/recurring-screenings/[id]Alertes delta (nouveaux hits)
À chaque run, le worker compare les hits obtenus aux hits du run précédent (par source). Toute nouvelle source qui produit un hit déclenche une screening_delta_alert + un webhook screening.delta_detected + un email au responsable LCB-FT + admins du cabinet.
# Liste des alertes non prises en compte
GET /api/recurring-screenings/delta-alerts
# Réponse
{
"alerts": [
{
"id": "da_...",
"recurringScreeningId": "rec_...",
"ficheVigilanceId": "fic_...",
"newHitsSources": ["ue", "ofac"],
"newHitsCount": 2,
"status": "unread",
"detectedAt": "2026-08-26T12:00:00.000Z"
}
]
}
# Marquer comme prise en compte par le responsable LCB-FT
POST /api/recurring-screenings/delta-alerts/[id]/acknowledgeRapport annuel
Export CSV avec synthèse (nb personnes surveillées, runs cumulés, hits détectés, alertes) + détail par alerte. Utile en cas de contrôle ACPR / CSN / CNB : justifie le respect de l'Art. L.561-6 CMF.
curl "https://conformitiel.fr/api/recurring-screenings/report?year=2026" \
-H "Authorization: Bearer cft_..." \
-o surveillance-2026.csv
# BOM UTF-8 + séparateur ; (compatible Excel FR)Analyse portefeuille
Endpoint agrege qui retourne la vue complete du portefeuille cabinet : tous les clients (fiches vigilance + audits SIREN + criblages), leurs beneficiaires effectifs, leurs dirigeants, avec detection automatique des patterns suspects (hubs, cross-hits, BE partages, structures nested).
Utilise en interne par la page /audits/graphe-portefeuille (4 onglets : Analyse, Focus radial, Alertes, Graphe global). L'endpoint est aussi accessible via Bearer token pour vos integrations externes (dashboards, exports vers votre CRM, alerting sur seuils).
GET /api/graphe-portefeuille
curl https://conformitiel.fr/api/graphe-portefeuille \
-H "Authorization: Bearer cft_..."
# Filtres optionnels (query params) :
GET /api/graphe-portefeuille?yearFrom=2025&yearTo=2026
GET /api/graphe-portefeuille?riskLevels=ELEVE,TRES_ELEVE
GET /api/graphe-portefeuille?onlyWithHits=true
GET /api/graphe-portefeuille?onlyHubs=trueStructure de la reponse
{
"nodes": [
{
"id": "pm:552100554",
"type": "auditedPM" | "ficheVigilancePM" | "ficheVigilancePP" | "personPP" | "personPM",
"label": "ACME Industries SAS",
"siren": "552100554",
"hasHit": false,
"isPPE": false,
"auditsCount": 1,
"fichesCount": 1,
"isHub": false, // true si personne liee a 2+ dossiers
"niveauVigilance": "STANDARD", // pour les fiches (utile pour blocs Analyse)
"dateProchainRevue": "2027-01-15"
}
],
"edges": [
{
"id": "e_1",
"source": "pm:552100554",
"target": "pp:martin_jean",
"type": "be" | "dirigeant" | "detient" | "audits" | "hub_share",
"label": "BE 45%"
}
],
"stats": {
"totalNodes": 34,
"totalEdges": 41,
"totalAudits": 9,
"totalFiches": 28,
"nbHits": 4,
"nbPPE": 3,
"nbHubs": 2,
"nbNestedStructures": 1
},
"alerts": [
{
"severity": "critical" | "warning" | "info",
"category": "hub" | "cross-hit" | "nested-structure",
"title": "...",
"description": "...",
"entities": ["ACME Industries SAS", "..."],
"articleCMF": "Art. L.561-10-2 CMF"
}
]
}POST /api/graphe-portefeuille/analyze — analyse IA optionnelle
Lance une passe d'analyse IA (Claude/OpenAI/Mistral) sur le graphe charge, qui detecte des patterns supplementaires (structuration, layering, coincidences comportementales). Necessite une cle IA configuree cote cabinet (BYOK — voir section AI).
curl -X POST https://conformitiel.fr/api/graphe-portefeuille/analyze \
-H "Authorization: Bearer cft_..."
# Retourne { alerts: PortfolioAlert[] } — meme format que les alertes deterministesCas d'usage integration
- Export CRM : synchroniser la liste des hubs et clients a risque eleve dans votre outil de suivi commercial
- Dashboard direction : afficher les KPI portefeuille dans un outil de BI (Metabase, Grafana, Tableau)
- Alerting seuil : trigger une notification Slack/Teams quand
nbHitsaugmente ou qu'un nouveau hub apparait - Rapport mensuel automatise : generer un PDF portefeuille pour votre direction generale ou pour un contro le ACPR programme
Provisioning partenaire (B2B2C)
Ce programme est réservé aux partenaires intégrateurs : chambres professionnelles, courtiers grossistes, éditeurs juridiques, cabinets experts-comptables revendeurs. Le partenaire provisionne N cabinets clients via API avec facturation groupée hors Stripe (facture PDF trimestrielle).
Isolation stricte v1 : le partenaire ne voit JAMAIS les données LCB-FT (fiches, audits, criblages) des cabinets. Il accède uniquement aux méta-données (nom, siren, admin users) et aux compteurs d'usage. Vous restez seul maître des données de vos cabinets clients.
Concrètement : un jeton cfp_ ne fonctionne que sur /api/partner/*. Pour lire ou produire des fiches, criblages, audits ou documents signés d'un cabinet, il faut un jeton cft_ créé pour un utilisateur de ce cabinet, qui hérite de son rôle. Toute tentative croisée reçoit un 401 explicite et est journalisée côté serveur.
Traçabilité : chaque action partenaire sur un cabinet (provisioning, invitation, archivage) est inscrite dans le journal de contrôle chaîné du cabinet avec votre identifiant partenaire et celui du jeton. Les jetons conservent créateur, dates de création, de révocation et de dernier usage.
Tokens Bearer cfp_
Distincts des tokens cft_(Structure+/Organisation/Enterprise). Format :cfp_<32 chars base64url>. Générés par notre équipe superadmin lors de l'onboarding partenaire, ensuite gérés depuis la console /partner/tokens.
7 scopes granulaires
orgs:createorgs:readorgs:archiveusers:createusers:readusage:read(compteurs uniquement, jamais le contenu)billing:read(usage cumulé contrat partenaire)tokens:manage(émettre / lister / révoquer les jetons cft_ d'un cabinet)*(full access, owner uniquement)
Provisionner un cabinet client
curl -X POST https://conformitiel.fr/api/partner/organizations \
-H "Authorization: Bearer cfp_..." \
-H "Content-Type: application/json" \
-d '{
"orgName": "Cabinet Dupont & Associés",
"siren": "123456789",
"profession": "notaire",
"adminEmail": "admin@cabinet-dupont.fr",
"adminName": "Jean Dupont"
}'
# Retourne 201 avec :
# {
# "organization": { "id": "...", "name": "...", "siren": "...", "profession": "notaire" },
# "adminUser": { "id": "...", "email": "...", "isNewUser": true },
# "magicLinkUrl": "https://conformitiel.fr/verify?token=...",
# "magicLinkExpiresAt": "2026-09-02T..."
# }
# Envoyez le magicLinkUrl a l'admin du cabinet — TTL 7j.Autres endpoints
GET /api/partner/me # info partenaire + token + usage
GET /api/partner/organizations # liste cabinets provisionnés
GET /api/partner/organizations/[id] # détail (meta + admins + usage)
POST /api/partner/organizations/[id]/archive # archive soft-delete
POST /api/partner/organizations/[id]/users # ajoute un user
GET /api/partner/organizations/[id]/users # liste users (email + role)
GET /api/partner/organizations/[id]/usage # compteurs mois en cours
GET /api/partner/usage # usage cumulé contrat
# Jetons cft_ du cabinet (scope tokens:manage) — le secret n'est retourné qu'une fois
POST /api/partner/organizations/[id]/tokens # { name, userId? | email?, expiresInDays? } → cft_ au nom d'un membre
GET /api/partner/organizations/[id]/tokens # liste (préfixes, dates, dernier usage)
DELETE /api/partner/organizations/[id]/tokens/[tokenId] # révocation
# Exception documentée : création d'un dossier notarial complet avec le cfp_ (+ organizationId)
POST /api/fiches-vigilance/notaire/dossier # scope orgs:create — écriture uniquementConsole UI partenaire
Une console dédiée est disponible sur /partner : dashboard KPI, provisioning UI, équipe (owner/operator), tokens API, facturation. L'accès requiert un compte user rattaché à l'équipe partenaire.
Facturation et quotas
Facture PDF trimestrielle basée sur votre usage (nombre de cabinets actifs, audits et screenings du trimestre). Les cabinets clients n'ont aucune dépendance Stripe. Quotas configurables (nb orgs, audits/mois, screenings/mois) — dépassement = 429 sur l'endpoint concerné.
Onboarding : ce programme n'est pas self-service pour l'instant. Contactez-nous via notre formulaire partenaire pour discuter d'un contrat.
Webhooks
Configurez 1..N endpoints par cabinet depuis /parametres/webhooks (rôle admin/dirigeant). À chaque évènement souscrit, Conformitiel envoie un POST JSON signé à l'URL choisie.
Évènements V1
import_batch.completed— Un batch d'import (fiches + criblage) est terminéimport_batch.failed— Un batch d'import a échoué en cours de traitementsignature.completed— Un signataire externe a signé un documentscreening.hit_detected— Un criblage a détecté un hit sanctions ou PPEscreening.delta_detected— Un recriblage automatique (surveillance continue) a détecté un nouveau hit qui n'existait pas au run précédentaudit.completed— Un audit SIREN a terminé son exécution
Format du payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "import_batch.completed",
"createdAt": "2026-08-25T14:32:11.000Z",
"organizationId": "org_abc123",
"data": {
"batchId": "batch_xyz789",
"filename": "clients-2026-08.xlsx",
"totalRows": 500,
"successRows": 487,
"errorRows": 13,
"skippedRows": 0
}
}Signature HMAC-SHA256
Chaque requête inclut un header X-Conformitiel-Signature au format t=<timestamp>,v1=<hex> (pattern Stripe). Le hex est le HMAC-SHA256 de "{timestamp}.{body}" avec le secret de l'endpoint comme clé.
Validation en Node.js
import crypto from 'node:crypto';
function verifyWebhook(secret, header, body) {
const parts = Object.fromEntries(
header.split(',').map(p => p.split('='))
);
const timestamp = parseInt(parts.t, 10);
const receivedSig = parts.v1;
// Anti-replay : refuse si > 5 min
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(receivedSig)
);
}
// Express handler
app.post('/webhooks/conformitiel', (req, res) => {
const rawBody = req.rawBody; // Attention : body BRUT, pas parsé
const header = req.headers['x-conformitiel-signature'];
if (!verifyWebhook(process.env.WEBHOOK_SECRET, header, rawBody)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(rawBody);
console.log('Received', event.type, event.data);
res.status(200).send('OK'); // impératif de renvoyer 2xx sinon retry
});Validation en Python
import hmac, hashlib, time
def verify_webhook(secret, header, body):
parts = dict(p.split('=') for p in header.split(','))
ts = int(parts['t'])
if abs(time.time() - ts) > 300:
return False
expected = hmac.new(
secret.encode(),
f"{ts}.{body}".encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, parts['v1'])Retry et abandon
- Timeout : 10s max par tentative
- Retry auto sur codes 5xx et 429 : après 1 min, 10 min, 1 h (4 tentatives max)
- Codes 4xx (sauf 429) : pas de retry, marqué
abandoned - Réponse 2xx attendue pour valider la livraison
- Historique des livraisons visible dans
/parametres/webhooks(endpoint expand)
Autres headers utiles
X-Conformitiel-Event— nom de l'évènement (redondant avec le body, pratique pour router sans parser)X-Conformitiel-Event-Id— UUID stable de l'évènement (dédup côté destinataire en cas de retry)X-Conformitiel-Delivery-Id— UUID de cette tentative précise (différent à chaque retry)
Rate limits
Les rate-limits protègent l'infrastructure et garantissent l'équité entre partenaires. Ils sont plus généreux pour les tokens partenaires (nous contacter pour élévation).
POST /api/screening
60 / min / token
POST /api/audit
10 / min / token (SSE)
POST /api/screening/batch
5 / heure / token
POST /api/fiches-vigilance
120 / min / token
GET /api/*
600 / min / token (lecture)
Webhooks entrants (portail collecte)
20 / 15min / token magic
En cas de dépassement : réponse 429 Too Many Requests avec header Retry-After (secondes à attendre). Aucune facturation additionnelle.
Sandbox partenaires
Environnement séparé de la production (base et stockage dédiés, même code, déployé à chaque mise en production) :
- URL :
https://sandbox.conformitiel.fr— mêmes routes, même OpenAPI (/api/docs) - Données synthétiques : cabinet d'exemple avec trois fiches pré-remplies, SIREN publics de sociétés cotées pour les audits (552032534, 542107651)
- Quotas de plan et de contrat illimités (rate-limits techniques conservés)
- Webhooks vers
http://localhostou un tunnel ngrok acceptés - Reset chaque dimanche 03:00 UTC : données des cabinets purgées, partenaires / utilisateurs / jetons / webhooks conservés
- Registres de sanctions et PPE réels, identiques à la production
- Chaque réponse porte
X-Conformitiel-Environment: sandbox; archives sans Object Lock ; sceaux vérifiables sur le vérificateur du sandbox
Accès immédiat en self-service : sandbox.conformitiel.fr/sandbox crée votre partenaire, votre jeton cfp_, un cabinet d'exemple et son jeton cft_ en un clic (email professionnel requis). Pour un partenaire de test sur mesure, écrivez à partenaires@conformitiel.fr.
Codes d'erreur standards
400
Bad Request — corps invalide (voir issues Zod si présents)
401
Unauthenticated — token absent, invalide ou expiré
403
Permission refusée (voir message : quel module + action)
404
Ressource introuvable dans cette organization
410
Ressource expirée (ex : lien signature expiré)
413
Payload trop grand (ex : upload > 50 Mo)
415
Content-Type non supporté (ex : upload MIME non whitelisté)
429
Rate limit dépassé — voir Retry-After
500
Erreur interne (log Sentry automatique côté serveur)
502
Sous-système externe indisponible (S3, INSEE, OpenSanctions)
Toutes les erreurs suivent un format JSON standard : { "error": "<message>", "issues"?: [...] }. Les messages sont toujours en français.
Fonctionnalités non exposées via l'API
Certaines fonctionnalités du produit sont volontairement accessibles uniquement depuis l'interface authentifiée du cabinet, et ne sont pas disponibles via l'API partenaires à ce jour.
Assistance IA (synthèses, brouillons DS, analyse portefeuille)
Le produit propose des fonctionnalités d'IA générative en mode BYOK (Bring Your Own Key) : chaque cabinet configure sa propre clé Anthropic ou OpenAI depuis Paramètres > IA. Ces fonctions ne sont pas exposées comme endpoints API partenaires — un intégrateur qui embarque Conformitiel n'a donc rien à provisionner côté IA. C'est le cabinet utilisateur qui active, sur son propre compte fournisseur, s'il le souhaite.
Détails techniques : Documentation sécurité — section IA (BYOK).
- Signature électronique par le client final (OTP par email, magic-link) : le déclenchement d'un envoi de signature au client se fait depuis l'interface. La signature simple du responsable du cabinet est, elle, automatique sur les livrables générés via l'API (voir « Documents signés et sceau vérifiable »).
- Portail de collecte de pièces client : la création d'une demande de collecte se fait depuis le back office cabinet. Une extension API est également envisagée.
Vous avez tout en main pour démarrer
Ouvrez la référence Scalar, générez un token en sandbox, lancez votre premier POC.