Environnement SANDBOX partenaires — données de test uniquement, purgées chaque dimanche à 03:00 UTC. Aucune valeur réglementaire. En savoir plus
Retour au portail partenaires

Guide API — Getting Started

Intégrez le criblage LCB-FT, les audits SIREN et la gestion des fiches vigilance en quelques appels REST.

Référence OpenAPI complète (Scalar)

Essayez chaque endpoint directement depuis le navigateur.

Ouvrir /api/docs

Parcours d'intégration de bout en bout

L'enchaînement exact des appels : onboarder une étude, obtenir son jeton, cribler, auditer, créer la fiche, produire le dossier CSN / ACPR, récupérer les PDF, faire signer.

Lire le parcours →

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

  1. Connectez-vous à l'application (rôle admin ou dirigeant).
  2. Rendez-vous dans /parametres/api-tokens.
  3. Cliquez sur "Générer un nouveau token" — libellé, rôle, expiration.
  4. 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,542107651

Events 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ées

Ce 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

  1. Upload multipart → détection colonnes + mapping auto
  2. Enregistrement du mapping user + consentement RGPD → validation
  3. Lancement du worker en fire-and-forget
  4. 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 skipped avec référence à la fiche existante.
  • Guard quota strict : dès que le quota mensuel est atteint, les lignes restantes sont marquées quota_exceeded sans dépassement silencieux.
  • Watchdog : un batch bloqué > 15 min sans progression est marqué failed par un cron.
  • Reprise : POST /api/imports/[batchId]/retry relance 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.completed ou import_batch.failed dispatch à 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_xyz789

Note : 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 paused

Cré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, annual

Ajuster / 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]/acknowledge

Rapport 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=true

Structure 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 deterministes

Cas 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 nbHits augmente 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:create orgs:read orgs:archive
  • users:create users:read
  • usage: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 uniquement

Console 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 traitement
  • signature.completed — Un signataire externe a signé un document
  • screening.hit_detected — Un criblage a détecté un hit sanctions ou PPE
  • screening.delta_detected — Un recriblage automatique (surveillance continue) a détecté un nouveau hit qui n'existait pas au run précédent
  • audit.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://localhost ou 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.