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. Créez votre clé API dans Paramètres → API.
- 2. Authentifiez-vous avec le header
Authorization: Bearer sk_live_… - 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.
| Endpoint | Mode | Prix unitaire |
|---|---|---|
| POST /v1/regulatory/ask | sync · 3-5 s | 0,10 € |
| POST /v1/screening/negative-news | async · 60-180 s | 0,80 € |
| GET /v1/jobs/:id | sync · < 100 ms | gratuit |
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