Vigilae Connect

Une API qui se lit avant de se signer.

La spécification est publique, les surfaces sont neutres, la signature des webhooks se vérifie en dix lignes chez vous. Cette page documente ce que l'API expose aujourd'hui — rien de plus, et c'est volontaire : ce qui n'est pas encore livré n'est pas documenté.

  • Spécification OpenAPI lisible sans clé ni compte
  • Jamais de déclaration de soupçon, jamais de verbatim client
  • Webhooks signés, vérifiables hors de Vigilae

Servie par l'API elle-même : le contrat que vous lisez est celui qui tourne.

Le périmètre

Des surfaces neutres, par construction.

L'API expose ce qu'un intégrateur peut consommer sans toucher au secret des dossiers : le journal de surveillance et des compteurs. Le contenu d'un dossier de vigilance, les pièces, les déclarations de soupçon ne transitent pas par cette API — ce n'est pas une limitation d'abonnement, c'est l'architecture.

Journal de surveillance

Les événements pKYC du cabinet — pièce expirée, changement de bénéficiaire effectif, re-criblage à traiter — sous forme neutre : séquence, type, gravité, date. Réponse toujours bornée à 500 événements.

Agrégats de portefeuille

Des compteurs, jamais un dossier : volumes par statut, retards, complétude. De quoi afficher un tableau de bord dans votre outil sans y faire entrer une donnée client.

Qualification

La seule écriture : qualifier un événement du journal (statut qualifie ou clos, disposition planifie, traite ou ecarte). Elle exige le scope écriture — le moindre privilège est la règle, pas l'option.

L'API est conçue server-to-server : une clé dans du code livré au navigateur est une clé publiée. Faites porter la clé par un proxy serveur, jamais par la page.

Les clés

Des clés scopées, montrées une fois, révocables tout de suite.

  • Format. Chaque clé commence par vgk_ et s'envoie en Authorization: Bearer vgk_…. Le secret n'est montré qu'à la création : seul son empreinte SHA-256 est conservée chez nous.
  • Scopes. lecture (défaut) et ecriture. Une clé sans le scope requis reçoit un 403 — voir #scopes.
  • Expiration. Un an après la création (visible dans la console du cabinet). Une clé échue reçoit un 401 explicite — voir #cle-expiree.
  • Débit. 60 requêtes/minute par clé (surchargeable par clé). Un 429 porte Retry-After et les en-têtes X-RateLimit-Limit / -Remaining / -Reset.
  • Révocation. Immédiate, depuis la console. La résolution se fait par empreinte : aucune énumération de clés n'est possible.
Quickstart

Trois appels curl, et vous avez fait le tour.

# Santé + authentification de la clé curl -s https://vigilae.org/api/v1/sante \ -H "Authorization: Bearer vgk_votre_cle" # Journal de surveillance, depuis le début, par pages de 100 curl -s "https://vigilae.org/api/v1/evenements?depuisSeq=0&limite=100" \ -H "Authorization: Bearer vgk_votre_cle" # Qualifier l'événement 42 (scope écriture) curl -s -X POST https://vigilae.org/api/v1/evenements/42/qualifier \ -H "Authorization: Bearer vgk_votre_cle" \ -H "Content-Type: application/json" \ -d '{"statut":"qualifie","disposition":"traite"}'

La pagination, en une règle

Passez depuisSeq (0 au premier appel) et limite (écrêtée à 500) : la réponse est triée par seq croissant et rend prochainSeq, à repasser tel quel à l'appel suivant. Une page plus courte que limite signifie la fin du journal — prochainSeq reste alors stable et sert de curseur de polling. Sans depuisSeq, vous obtenez la vue « plus récents d'abord », bornée à 500.

Le portefeuille s'interroge sur /api/v1/portefeuille/agregats — des compteurs, une réponse, pas de pagination.

Webhooks

Signés, horodatés, livrés au moins une fois.

Plutôt que d'interroger le journal, recevez-le : Vigilae livre les événements à votre URL, dans l'ordre, par lots de 100 au maximum. La livraison est at-least-once — le curseur n'avance que sur votre 2xx, lot par lot — et l'idempotence se fait par seq : traitez chaque séquence une seule fois (#idempotence).

Vérifier la signature

Chaque livraison porte l'en-tête x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + corps). Recalculez v1 depuis le corps brut reçu, et rejetez tout horodatage t au-delà de 5 minutes : c'est l'anti-rejeu. Pendant une rotation de secret, l'en-tête porte un v1 par secret encore valide (chevauchement de 24 h) : acceptez si l'un correspond.

// Node — vérification de signature (aucune dépendance) import { createHmac, timingSafeEqual } from 'node:crypto'; export function signatureValide(entete, corpsBrut, secrets, toleranceMs = 5 * 60 * 1000) { const t = Number((/(?:^|,)t=(\d+)/.exec(entete) || [])[1]); if (!t || Math.abs(Date.now() - t * 1000) > toleranceMs) return false; // anti-rejeu const recus = [...entete.matchAll(/v1=([0-9a-f]{64})/g)].map((m) => m[1]); return [].concat(secrets).some((secret) => { const attendu = createHmac('sha256', secret).update(t + '.' + corpsBrut).digest('hex'); return recus.some((r) => r.length === attendu.length && timingSafeEqual(Buffer.from(r), Buffer.from(attendu))); }); }
# Python — même vérification import hmac, hashlib, re, time def signature_valide(entete: str, corps_brut: bytes, secrets, tolerance_s: int = 300) -> bool: m = re.search(r"(?:^|,)t=(\d+)", entete) if not m or abs(time.time() - int(m.group(1))) > tolerance_s: return False # anti-rejeu recus = re.findall(r"v1=([0-9a-f]{64})", entete) for secret in secrets: attendu = hmac.new(secret.encode(), m.group(1).encode() + b"." + corps_brut, hashlib.sha256).hexdigest() if any(hmac.compare_digest(attendu, r) for r in recus): return True return False

Transitoire : l'ancien format sha256=HMAC(corps) est encore émis sur x-vigilae-signature-legacy pour les récepteurs déjà en place ; son retrait est prévu avec les webhooks v2. Les nouveaux récepteurs vérifient le schéma horodaté ci-dessus, pas l'ancien.

La rotation se déclenche depuis la console (POST /connect/webhook/rotation côté application) : pendant 24 h, l'ancien secret signe encore — le temps de déployer le nouveau chez vous sans fenêtre d'échec.

Environnement d'essai

Sandbox : sur demande.

Il n'existe pas encore de sandbox en libre-service — nous préférons vous le dire ici plutôt que de vous le laisser découvrir. Écrivez à contact@vigilae.org (objet « Accès API ») : nous ouvrons un cabinet d'essai avec des données fictives, le temps de votre intégration, et nous restons joignables pendant qu'elle avance.

Les erreurs de l'API ont chacune une adresse stable sur la référence des erreurs : #authentification, #scopes, #cloisonnement, #debit, #signature… Les réponses d'erreur de l'API renverront vers ces ancres.

L'API n'expose ni déclaration de soupçon ni verbatim client, par construction (art. L.561-18 CMF). Aucune décision de vigilance n'est prise par l'API : elle expose et qualifie des événements, le professionnel décide.