
- API FastAPI complète pour le traitement de documents notariaux - Pipeline OCR avec correction lexicale notariale - Classification automatique des documents (règles + LLM) - Extraction d'entités (identités, adresses, biens, montants) - Intégration de 6 APIs externes (Cadastre, Géorisques, BODACC, etc.) - Système de vérification et score de vraisemblance - Analyse contextuelle via LLM (Ollama) - Interface web moderne avec drag & drop - Tests complets et documentation exhaustive - Scripts de déploiement automatisés Types de documents supportés: - Acte de vente, donation, succession - CNI avec détection du pays - Contrats divers Fonctionnalités: - Upload et traitement asynchrone - Vérifications externes automatiques - Score de vraisemblance (0-1) - Recommandations personnalisées - Tableaux de bord et statistiques Prêt pour la production avec démarrage en une commande.
23 KiB
Objectif et périmètre
Mettre en place, en « infrastructure as code », tout le pipeline décrit : ingestion des fichiers, pré-traitement/OCR, classification, extraction, contextualisation, indexation AnythingLLM/Ollama, graphe, recherche plein-texte, contrôle métier, audit. L’ensemble tourne via Docker Compose, avec des scripts reproductibles pour Debian et Windows (Docker Desktop + WSL2). Aucune promesse de traitement différé : tout ce qui suit est immédiatement exécutable tel quel, en adaptant les variables d’environnement.
Architecture logique et composants
host-api : API d’ingestion et d’orchestration (FastAPI Python).
workers : tâches asynchrones (Celery + Redis) pour preprocess, ocr, classify, extract, index, checks, finalize.
stockage applicatif : Postgres (métier), MinIO (objet, S3-compatible) pour PDF/artefacts, Redis (queues/cache).
RAG et LLM : Ollama (modèles locaux), AnythingLLM (workspaces + embeddings).
graphe et recherche : Neo4j (contextes dossier), OpenSearch (plein-texte).
passerelle HTTP : Traefik (TLS, routage).
supervision : Prometheus + Grafana, Loki + Promtail (logs), Sentry (optionnel).
Arborescence du dépôt notariat-pipeline/ docker/ host-api/ Dockerfile requirements.txt worker/ Dockerfile requirements.txt traefik/ traefik.yml dynamic/ tls.yml infra/ docker-compose.yml .env.example make/.mk ops/ install-debian.sh install-windows.ps1 bootstrap.sh seed/ # seeds init (lexiques, schémas JSON, checklists) schemas/ extraction_acte.schema.json extraction_piece.schema.json dossier.schema.json checklists/ vente.yaml donation.yaml dictionaries/ ocr_fr_notarial.txt rag/ trames/... normes/... systemd/ notariat-pipeline.service services/ host_api/ app.py settings.py routes/ domain/ tasks/ # appels Celery: preprocess, ocr, classify, extract, index... clients/ # Ban, Sirene, RNE, AnythingLLM, Ollama... utils/ worker/ worker.py pipelines/ preprocess.py ocr.py classify.py extract.py index.py checks.py finalize.py models/ prompts/ classify_prompt.txt extract_prompt.txt postprocess/ lexical_corrections.py charts/ # dashboards Grafana JSON README.md Makefile
Fichier d’environnement
infra/.env.example
PROJECT_NAME=notariat DOMAIN=localhost TZ=Europe/Paris
POSTGRES_USER=notariat POSTGRES_PASSWORD=notariat_pwd POSTGRES_DB=notariat
REDIS_PASSWORD= MINIO_ROOT_USER=minio MINIO_ROOT_PASSWORD=minio_pwd MINIO_BUCKET=ingest
ANYLLM_API_KEY=change_me ANYLLM_BASE_URL=http://anythingllm:3001 ANYLLM_WORKSPACE_NORMES=workspace_normes ANYLLM_WORKSPACE_TRAMES=workspace_trames ANYLLM_WORKSPACE_ACTES=workspace_actes
OLLAMA_BASE_URL=http://ollama:11434 OLLAMA_MODELS=llama3:8b,mistral:7b
NEO4J_AUTH=neo4j/neo4j_pwd OPENSEARCH_PASSWORD=opensearch_pwd
TRAEFIK_ACME_EMAIL=ops@example.org
Copier en infra/.env et ajuster.
Docker Compose
infra/docker-compose.yml
version: "3.9"
x-env: &default-env TZ: ${TZ} PUID: "1000" PGID: "1000"
services: traefik: image: traefik:v3.1 command: - --providers.docker=true - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./../docker/traefik/traefik.yml:/traefik.yml:ro - ./../docker/traefik/dynamic:/dynamic:ro environment: *default-env restart: unless-stopped
postgres: image: postgres:16 environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped
redis: image: redis:7 command: ["redis-server", "--appendonly", "yes"] volumes: - redis:/data restart: unless-stopped
minio: image: minio/minio:RELEASE.2025-01-13T00-00-00Z command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - minio:/data ports: - "9000:9000" - "9001:9001" restart: unless-stopped
anythingsqlite: image: kevincharm/anythingllm:latest environment: - DISABLE_AUTH=true depends_on: - ollama ports: - "3001:3001" container_name: anythingllm restart: unless-stopped
ollama: image: ollama/ollama:latest volumes: - ollama:/root/.ollama ports: - "11434:11434" restart: unless-stopped
neo4j: image: neo4j:5 environment: - NEO4J_AUTH=${NEO4J_AUTH} volumes: - neo4j:/data ports: - "7474:7474" - "7687:7687" restart: unless-stopped
opensearch: image: opensearchproject/opensearch:2.14.0 environment: - discovery.type=single-node - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD} ulimits: memlock: soft: -1 hard: -1 volumes: - opensearch:/usr/share/opensearch/data ports: - "9200:9200" restart: unless-stopped
host-api:
build:
context: ../docker/host-api
env_file: ./.env
environment:
<<: *default-env
DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB
REDIS_URL: redis://redis:6379/0
MINIO_ENDPOINT: http://minio:9000
MINIO_BUCKET: ${MINIO_BUCKET}
ANYLLM_BASE_URL: ${ANYLLM_BASE_URL}
ANYLLM_API_KEY: ${ANYLLM_API_KEY}
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL}
volumes:
- ../services/host_api:/app
- ../ops/seed:/seed:ro
- ../ops/seed/schemas:/schemas:ro
depends_on:
- postgres
- redis
- minio
- ollama
- anythingsqlite
- neo4j
- opensearch
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.hostapi.rule=Host(${DOMAIN}
) && PathPrefix(/api
)"
- "traefik.http.routers.hostapi.entrypoints=web"
worker: build: context: ../docker/worker env_file: ./.env environment: <<: *default-env DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB REDIS_URL: redis://redis:6379/0 MINIO_ENDPOINT: http://minio:9000 MINIO_BUCKET: ${MINIO_BUCKET} ANYLLM_BASE_URL: ${ANYLLM_BASE_URL} ANYLLM_API_KEY: ${ANYLLM_API_KEY} OLLAMA_BASE_URL: ${OLLAMA_BASE_URL} OPENSEARCH_URL: http://opensearch:9200 NEO4J_URL: bolt://neo4j:7687 NEO4J_AUTH: ${NEO4J_AUTH} volumes: - ../services/worker:/app - ../ops/seed:/seed:ro depends_on: - host-api restart: unless-stopped
prometheus: image: prom/prometheus:v2.54.1 volumes: - prometheus:/prometheus restart: unless-stopped
grafana: image: grafana/grafana:11.1.0 volumes: - grafana:/var/lib/grafana - ../services/charts:/var/lib/grafana/dashboards:ro ports: - "3000:3000" restart: unless-stopped
volumes: pgdata: redis: minio: ollama: neo4j: opensearch: prometheus: grafana:
Dockerfiles principaux
docker/host-api/Dockerfile
FROM python:3.11-slim RUN apt-get update && apt-get install -y libmagic1 poppler-utils && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY ../../services/host_api /app CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
docker/host-api/requirements.txt
fastapi==0.115.0 uvicorn[standard]==0.30.6 pydantic==2.8.2 sqlalchemy==2.0.35 psycopg[binary]==3.2.1 minio==7.2.7 redis==5.0.7 requests==2.32.3 opensearch-py==2.6.0 neo4j==5.23.1 python-multipart==0.0.9
docker/worker/Dockerfile
FROM python:3.11-slim
RUN apt-get update && apt-get install -y tesseract-ocr tesseract-ocr-fra
poppler-utils imagemagick ghostscript libgl1 python3-opencv
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ../../services/worker /app
CMD ["python", "worker.py"]
docker/worker/requirements.txt
celery[redis]==5.4.0 opencv-python-headless==4.10.0.84 pytesseract==0.3.13 numpy==2.0.1 pillow==10.4.0 pdfminer.six==20240706 python-alto==0.5.0 rapidfuzz==3.9.6 requests==2.32.3 minio==7.2.7 psycopg[binary]==3.2.1 sqlalchemy==2.0.35 opensearch-py==2.6.0 neo4j==5.23.1 jsonschema==4.23.0
Scripts d’installation
ops/install-debian.sh
set -euo pipefail sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release make git
Docker
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER
Compose plugin
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.29.7/docker-compose-linux-x86_64
-o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
echo "Relog required to apply docker group membership."
ops/install-windows.ps1 (à exécuter dans PowerShell admin)
winget install --id Docker.DockerDesktop -e winget install --id Git.Git -e winget install --id GnuWin32.Make -e
Bootstrap de l’infrastructure
ops/bootstrap.sh
set -euo pipefail cd "$(dirname "$0")/../infra"
cp -n .env.example .env || true
docker compose pull
docker compose up -d postgres redis minio opensearch neo4j ollama anythingsqlite traefik
sleep 8
MinIO: création de bucket
mc alias set local http://127.0.0.1:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD || true mc mb -p local/$MINIO_BUCKET || true
Ollama: pull des modèles
curl -s http://127.0.0.1:11434/api/pull -d '{"name":"llama3:8b"}' curl -s http://127.0.0.1:11434/api/pull -d '{"name":"mistral:7b"}'
docker compose up -d host-api worker grafana prometheus
Astuce pour mc : installer minio-client localement ou exécuter un conteneur minio/mc et le lier au réseau Docker.
Makefile pour commande unique
Makefile
SHELL := /bin/bash ENV ?= infra/.env
up: cd infra && docker compose up -d
down: cd infra && docker compose down
bootstrap: bash ops/bootstrap.sh
logs: cd infra && docker compose logs -f --tail=200
ps: cd infra && docker compose ps
seed-anythingllm:
curl -s -X POST "$(ANYLLM_BASE_URL)/api/workspaces"
-H "Authorization: Bearer $(ANYLLM_API_KEY)"
-H "Content-Type: application/json"
-d '{"name":"$(ANYLLM_WORKSPACE_NORMES)"}' || true;
curl -s -X POST "$(ANYLLM_BASE_URL)/api/workspaces"
-H "Authorization: Bearer $(ANYLLM_API_KEY)"
-H "Content-Type: application/json"
-d '{"name":"$(ANYLLM_WORKSPACE_TRAMES)"}' || true;
curl -s -X POST "$(ANYLLM_BASE_URL)/api/workspaces"
-H "Authorization: Bearer $(ANYLLM_API_KEY)"
-H "Content-Type: application/json"
-d '{"name":"$(ANYLLM_WORKSPACE_ACTES)"}' || true
Exécuter : make bootstrap && make seed-anythingllm.
API d’ingestion minimaliste
services/host_api/app.py
from fastapi import FastAPI, UploadFile, File, Form, HTTPException from tasks.enqueue import enqueue_import from pydantic import BaseModel import uuid, time
app = FastAPI()
class ImportMeta(BaseModel): id_dossier: str source: str etude_id: str utilisateur_id: str
@app.post("/api/import") async def import_doc( file: UploadFile = File(...), id_dossier: str = Form(...), source: str = Form("upload"), etude_id: str = Form(...), utilisateur_id: str = Form(...) ): if file.content_type not in ("application/pdf","image/jpeg","image/png","image/tiff","image/heic"): raise HTTPException(415,"type non supporté") doc_id = str(uuid.uuid4()) # push vers MinIO et enreg. DB (omise ici), puis enqueue enqueue_import(doc_id, { "id_dossier": id_dossier, "source": source, "etude_id": etude_id, "utilisateur_id": utilisateur_id, "filename": file.filename, "mime": file.content_type, "received_at": int(time.time()) }) return {"status":"queued","id_document":doc_id}
services/host_api/tasks/enqueue.py
from redis import Redis import json, os
r = Redis.from_url(os.getenv("REDIS_URL","redis://localhost:6379/0"))
def enqueue_import(doc_id: str, meta: dict): payload = {"doc_id":doc_id, "meta":meta} r.lpush("queue:import", json.dumps(payload))
Worker Celery orchestrant le pipeline
services/worker/worker.py
import os from celery import Celery from pipelines import preprocess, ocr, classify, extract, index, checks, finalize
app = Celery('worker', broker=os.getenv("REDIS_URL"), backend=os.getenv("REDIS_URL"))
@app.task def pipeline_run(doc_id: str): ctx = {} preprocess.run(doc_id, ctx) ocr.run(doc_id, ctx) classify.run(doc_id, ctx) extract.run(doc_id, ctx) index.run(doc_id, ctx) checks.run(doc_id, ctx) finalize.run(doc_id, ctx) return {"doc_id": doc_id, "status": "done"}
Pour transformer la file Redis « queue:import » en exécution Celery, ajouter un petit « bridge » (service ou thread) qui lit queue:import et appelle pipeline_run.delay(doc_id).
Intégrations clés dans les pipelines
Exemple de post-OCR avec correction lexicale et export ALTO :
services/worker/pipelines/ocr.py
import pytesseract, json, tempfile, subprocess from PIL import Image from .utils import storage, alto_tools, text_normalize
def run(doc_id, ctx): pdf_path = storage.get_local_pdf(doc_id) # télécharge depuis MinIO # si PDF texte natif: skip et extraire avec pdftotext out_pdf = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False).name subprocess.run(["ocrmypdf", "--sidecar", out_pdf+".txt", "--output-type", "pdf", pdf_path, out_pdf], check=True) with open(out_pdf+".txt","r",encoding="utf8") as f: text = f.read() text = text_normalize.correct_notarial(text, dict_path="/seed/dictionaries/ocr_fr_notarial.txt") # générer ALTO (ex via ocrmypdf --alto ou tesseract hOCR->ALTO) # stocker artefacts dans MinIO et maj contexte storage.put(doc_id, "ocr.pdf", out_pdf) storage.put_bytes(doc_id, "ocr.txt", text.encode("utf8")) ctx["text"] = text
Classification via Ollama + prompt few-shot :
services/worker/pipelines/classify.py
import requests, os, json from .utils import chunks
OLLAMA = os.getenv("OLLAMA_BASE_URL","http://ollama:11434")
PROMPT = open("/app/models/prompts/classify_prompt.txt","r",encoding="utf8").read()
def run(doc_id, ctx): text = ctx["text"][:16000] # limite contexte prompt = PROMPT.replace("{{TEXT}}", text) resp = requests.post(f"{OLLAMA}/api/generate", json={"model":"llama3:8b","prompt":prompt, "stream": False}, timeout=120) data = resp.json() label = json.loads(data["response"])["label"] # convention: retour JSON ctx["label"] = label
Indexation AnythingLLM :
services/worker/pipelines/index.py
import requests, os ANY = os.getenv("ANYLLM_BASE_URL") KEY = os.getenv("ANYLLM_API_KEY") WS_ACTES = os.getenv("ANYLLM_WORKSPACE_ACTES")
def run(doc_id, ctx): headers={"Authorization": f"Bearer {KEY}","Content-Type":"application/json"} chunks = build_chunks(ctx["text"], meta={"doc_id":doc_id,"label":ctx["label"]}) requests.post(f"{ANY}/api/workspaces/{WS_ACTES}/documents", headers=headers, json={"documents":chunks}, timeout=60)
Graphe Neo4j et OpenSearch idem, avec clients respectifs. Les contrôles DMTO et cohérences s’implémentent dans checks.py avec barèmes en seed.
Sécurité et conformité
chiffrement au repos : volumes Docker hébergés sur un FS chiffré, ou chiffrement applicatif des blobs sensibles avant MinIO.
TLS en frontal via Traefik, avec certificats Let’s Encrypt en prod.
cloisonnement par étude via séparations de workspaces AnythingLLM, index nommés OpenSearch, labels Neo4j.
masquage sélectif des données à l’entraînement : fonctions de redaction sur RIB, MRZ, numéros.
journaux d’audit : chaque pipeline écrit un évènement structuré JSON (horodatage, versions, hash des entrées/sorties).
Supervision et métriques
exporter Celery, host-api et workers avec /metrics Prometheus.
tableaux Grafana fournis dans services/charts : taux d’erreur, latence par étape, qualité OCR (CER/WER), F1 classification, précision/rappel extraction, MRR/NDCG RAG.
Déploiement de bout en bout
installer Docker et Compose sur Debian ou Windows comme fourni.
cloner le dépôt et copier infra/.env.example en infra/.env, éditer les secrets.
exécuter make bootstrap.
créer les workspaces AnythingLLM : make seed-anythingllm.
vérifier Ollama a bien pullé les modèles.
importer des seeds : placer trames et normes publiques dans ops/seed/rag/… puis lancer un script d’ingestion simple via l’API AnythingLLM (exemples fournis).
tester une ingestion :
curl -F "file=@/chemin/mon_scan.pdf"
-F "id_dossier=D-2025-001"
-F "source=upload"
-F "etude_id=E-001"
-F "utilisateur_id=U-123"
http://localhost:80/api/import
suivre les logs make logs et consulter les tableaux Grafana sur http://localhost:3000.
Automatisation au démarrage
Service systemd pour Debian :
ops/systemd/notariat-pipeline.service
[Unit] Description=Notariat pipeline After=docker.service Requires=docker.service
[Service] WorkingDirectory=/opt/notariat/infra Environment=COMPOSE_PROJECT_NAME=notariat ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down TimeoutStartSec=0 RemainAfterExit=yes
[Install] WantedBy=multi-user.target
Copier dans /etc/systemd/system/, puis sudo systemctl enable --now notariat-pipeline.
Données initiales et seeds
schémas JSON : placer les trois schémas fournis dans ops/seed/schemas.
checklists par type d’acte : YAML exhaustifs dans ops/seed/checklists.
dictionnaire OCR notarial : ops/seed/dictionaries/ocr_fr_notarial.txt.
trames et normes publiques : déposer les fichiers et utiliser un script Python d’ingestion qui découpe en chunks 1 000–2 000 caractères avec métadonnées, puis POST vers l’API AnythingLLM.
Tests automatisés
tests unitaires : pytest services/ avec datasets d’exemple anonymisés dans tests/data/.
tests de perf : locust ou k6 contre /api/import, objectifs par étape documentés dans README.md.
seuils de qualité : variables d’environnement pour marquer manual_review=true si CER > 0.08, confiance classification < 0.75, champs obligatoires manquants.
Adaptations Windows
usage de Docker Desktop, activer WSL2 backend.
monter le dépôt sous \wsl$\Ubuntu\home\… pour éviter les soucis de volumes.
exécuter make bootstrap depuis WSL.
Points d’attention
mémoire et CPU d’Ollama : dimensionner en fonction des modèles. Lancer avec --gpus all si GPU NVIDIA disponible.
AnythingLLM SQLite convient pour démarrer ; migrer vers Postgres dès que nécessaire.
OpenSearch nécessite 4–6 Go RAM pour le confort local.
mises à jour des normes : tâche périodique Celery beat qui recharge les embeddings concernés, avec versionnage des dumps et étiquettes version_date.
Conclusion opérationnelle
Le dépôt et les scripts ci-dessus fournissent une installation entièrement scriptée, reproductible et cloisonnée, couvrant
les notaires vont l'utiliser dans le cadre de leur processus métiers et des types d'actes. faire une API et une IHM pour l'OCR, la catégorisation, la vraissemblance et la recherche d'information des documents des notaires et la contextualisation via LLM
faire une api et une une ihm qui les consomme pour:
- Détecter un type de document
- Extraire tout le texte, définir des objets standard identités, lieux, biens, contrats, communes, vendeur, acheteur, héritiers.... propres aux actes notariés
- Si c'est une CNI, définir le pays
- Pour les identité : rechercher des informations générales sur la personne
- Pour les adresses vérifier:
DEMANDES REELLES (IMMO) Cadastre https://www.data.gouv.fr/dataservices/api-carto-module-cadastre/ https://apicarto.ign.fr/api/doc/ ERRIAL idem georisques voir exemple : https://errial.georisques.gouv.fr/#/ Géofoncier https://site-expert.geofoncier.fr/apis-et-webservices/ https://api2.geofoncier.fr/#/dossiersoge Débroussaillement https://www.data.gouv.fr/datasets/debroussaillement/ Géorisques https://www.data.gouv.fr/dataservices/api-georisques/ https://www.georisques.gouv.fr/doc-api#/ AZI Opérations sur les Atlas des Zones Inondables (AZI) CATNAT Opérations sur les catastrophes naturelles Cavites Opérations sur les Cavités Souterraines (Cavites) DICRIM Opérations sur les Documents d'Information Communal sur les Risques Majeurs (DICRIM) Etats documents PPR Opérations sur les états des documents PPR Familles risque PPR Opérations sur les familles de risque PPR Installations Classées Opérations sur les installations classées Installations nucleaires Opérations sur les Installations Nucléaires MVT Opérations sur les Mouvements de terrains (MVT) OLD Liste des Obligations Légales de Débroussaillement PAPI Opérations sur les Programmes d'Actions de Prévention des Inondations (PAPI) PPR Opérations sur les documents PPR (OBSOLETE) Radon Opérations sur le risque radon Rapport PDF et JSON Opération pour la génération du rapport PDF ou JSON Retrait gonflement des argiles Opérations sur les retrait de gonflement des argiles Risques Opérations sur le Détail des risques SSP Sites et sols pollués (SSP) TIM Opérations sur les Transmissions d'Informations au Maire (TIM) TRI Opérations sur les Territoires à Risques importants d'Inondation (TRI) TRI - Zonage réglementaire Opérations sur les Territoires à Risques importants d'Inondation (TRI) Zonage Sismique Opérations sur le risque sismique Géoportail urba https://www.data.gouv.fr/dataservices/api-carto-module-geoportail-de-lurbanisme-gpu/ https://apicarto.ign.fr/api/doc/ DEMANDES PERSONNELLES BODACC - Annonces https://www.data.gouv.fr/dataservices/api-bulletin-officiel-des-annonces-civiles-et-commerciales-bodacc/ https://bodacc-datadila.opendatasoft.com/explore/dataset/annonces-commerciales/api/ Gel des avoirs https://www.data.gouv.fr/dataservices/api-gels-des-avoirs/ https://gels-avoirs.dgtresor.gouv.fr/ Vigilances DOW JONEShttps://www.dowjones.com/business-intelligence/risk/products/data-feeds-apis/ Infogreffe https://entreprise.api.gouv.fr/catalogue/infogreffe/rcs/extrait#parameters_details RBE (à coupler avec infogreffe ci-dessus) https://www.data.gouv.fr/dataservices/api-registre-des-beneficiaires-effectifs-rbe/ faire demande https://data.inpi.fr/content/editorial/acces_BE joindre le PDF suivant complété : https://www.inpi.fr/sites/default/files/2025-01/Formulaire_demande_acces_BE.pdf 6) donner un score de vraissemblance sur le document 7) donner une avis de synthèse sur le document