Documentation · API v1

API LCB-FT pour développeurs

Intégrez notre intelligence anti-blanchiment dans vos propres outils via une API REST simple et facturée à l'usage. Trois endpoints disponibles, une clé Bearer, pas d'abonnement.

En 30 secondes

  1. 1. Créez votre clé API dans Paramètres → API.
  2. 2. Authentifiez-vous avec le header Authorization: Bearer sk_live_…
  3. 3. Appelez les endpoints en JSON. Chaque appel réussi est facturé en fin de mois.

Tarification

Pay-per-call. Pas d'abonnement, pas de minimum mensuel. Les erreurs (4xx, 5xx) ne sont pas facturées.

EndpointModePrix unitaire
POST /v1/regulatory/asksync · 3-5 s0,10 €
POST /v1/screening/negative-newsasync · 60-180 s0,80 €
GET /v1/jobs/:idsync · < 100 msgratuit

Authentification

Toutes les requêtes nécessitent un header Authorization: Bearer <token>. Le token n'est révélé qu'une fois à la création — stockez-le dans votre gestionnaire de secrets.

curl https://lutteblanchiment.com/v1/regulatory/ask \
  -H "Authorization: Bearer sk_live_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{"question": "Quel est le seuil KYC pour un négociant ?"}'

Codes d'erreur d'auth : 401 missing_authorization, 401 invalid_token, 401 revoked_token, 429 rate_limit_exceeded.

POST /v1/regulatory/ask

Pose une question réglementaire LCB-FT (CMF, AMLR, AMLAR, lignes directrices ACPR/AMF/ANJ). Retourne une réponse argumentée avec sources citées inline.

Requête

POST /v1/regulatory/ask
Content-Type: application/json
Authorization: Bearer sk_live_…

{
  "question": "Que dit l'article 36 de l'AMLAR ?"
}

Réponse 200

{
  "answer": "L'article 36 du règlement AMLAR (UE) 2024/1620 prévoit que l'AMLA contribue à la mise en place et au fonctionnement des collèges de surveillance LBC-FT dans le secteur non financier [Source 1]…",
  "sources": [
    {
      "ref": "AMLR art. 36",
      "url": "https://eur-lex.europa.eu/...",
      "title": "Règlement (UE) 2024/1620"
    }
  ],
  "model": "claude-haiku-4-5-20251001",
  "duration_ms": 4231
}

POST /v1/screening/negative-news

Lance un screening adverse media en sources ouvertes (presse, justice, sanctions). Endpoint asynchrone : l'appel POST retourne immédiatement un job_id, le résultat est récupéré via GET /v1/jobs/:id en polling.

Étape 1 — Créer le job

POST /v1/screening/negative-news
Content-Type: application/json
Authorization: Bearer sk_live_…

{
  "name": "Patrick Drahi",
  "type": "personne_physique",
  "nationality": "FR",
  "date_of_birth": "1963-08-20"
}

← 202 Accepted

{
  "job_id": "scr_01H7FX...",
  "status": "pending",
  "polling_url": "/v1/jobs/scr_01H7FX...",
  "estimated_duration_seconds": 60,
  "created_at": "2026-04-30T22:14:00Z"
}

Étape 2 — Polling jusqu'à completion

GET /v1/jobs/scr_01H7FX...
Authorization: Bearer sk_live_…

← 200 (encore en cours)

{
  "job_id": "scr_01H7FX...",
  "status": "running",
  "started_at": "2026-04-30T22:14:01Z",
  "kind": "screening_negative_news"
}

← 200 (terminé, après 60-180s)

{
  "job_id": "scr_01H7FX...",
  "status": "completed",
  "completed_at": "2026-04-30T22:15:23Z",
  "result": {
    "subject": { "name": "Patrick Drahi", "type": "personne_physique" },
    "risk_score": 7,
    "risk_level": "eleve",
    "summary": "Sujet médiatisé...",
    "hits": [...],
    "categories_detected": ["litige_judiciaire", "evasion_fiscale"],
    "recommendation": "Vigilance renforcée requise.",
    "sources_count": 12
  }
}

Conseil : poll toutes les 3-5 secondes. Le job a une durée de vie de 7 jours, après quoi il est purgé. Les statuts possibles sont pending, running, completed, failed, expired.

Exemple complet (Node.js)

async function screenSubject(name) {
  const apiKey = process.env.MALCBFT_API_KEY;
  const baseUrl = "https://lutteblanchiment.com";

  // 1. Create the job
  const post = await fetch(`${baseUrl}/v1/screening/negative-news`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ name, type: "personne_physique" }),
  });
  const { job_id } = await post.json();

  // 2. Poll until completion
  while (true) {
    await new Promise((r) => setTimeout(r, 4000));
    const poll = await fetch(`${baseUrl}/v1/jobs/${job_id}`, {
      headers: { "Authorization": `Bearer ${apiKey}` },
    });
    const job = await poll.json();
    if (job.status === "completed") return job.result;
    if (job.status === "failed") throw new Error(job.error);
  }
}

const report = await screenSubject("Patrick Drahi");
console.log(report.risk_score, report.summary);

Exemple complet (Python)

import os, time, requests

API_KEY = os.environ["MALCBFT_API_KEY"]
BASE = "https://lutteblanchiment.com"
HDRS = {"Authorization": f"Bearer {API_KEY}"}

def screen_subject(name: str) -> dict:
    r = requests.post(
        f"{BASE}/v1/screening/negative-news",
        headers={**HDRS, "Content-Type": "application/json"},
        json={"name": name, "type": "personne_physique"},
    )
    r.raise_for_status()
    job_id = r.json()["job_id"]

    while True:
        time.sleep(4)
        job = requests.get(f"{BASE}/v1/jobs/{job_id}", headers=HDRS).json()
        if job["status"] == "completed":
            return job["result"]
        if job["status"] == "failed":
            raise RuntimeError(job["error"])

report = screen_subject("Patrick Drahi")
print(report["risk_score"], report["summary"])

Limites & erreurs

  • Rate limit : 60 req/min par clé par défaut. Au-delà, 429 rate_limit_exceeded.
  • Taille question : 2000 caractères maximum (regulatory/ask).
  • TTL des jobs : 7 jours après création. Au-delà, statut expired.
  • Format des erreurs : { "error": { "code": "...", "message": "..." } }

Besoin de volumes plus élevés, d'un endpoint custom, ou d'un SLA contractuel ?

Nous contacter