Een API die u kunt lezen vóór u tekent.
De specificatie is publiek, de webhookhandtekening is in tien regels aan uw kant te verifiëren. Deze pagina documenteert wat de API vandaag blootlegt — niets meer, en dat is bewust: wat niet is uitgeleverd, wordt niet gedocumenteerd.
- OpenAPI-specificatie leesbaar zonder sleutel of account
- Nooit een melding van een ongebruikelijke transactie, nooit letterlijke cliëntinhoud
- Ondertekende webhooks, verifieerbaar buiten Vigilae
Geserveerd door de API zelf: het contract dat u leest, is het contract dat draait.
Het volledige traject, en twee uitsluitingen die vastliggen.
Uw software kan een dossier van begin tot eind afhandelen: de cliënt aanmaken, het dossier openen, de documenten uploaden, de screening starten, de uiteindelijk begunstigden opgeven, de risicobeoordeling lezen en het bewijsdossier ophalen. Twee dingen zullen daar nooit doorheen lopen, en dat is geen beperking van het abonnement: geen enkele melding van een ongebruikelijke transactie, en geen enkele letterlijke uitspraak van uw cliënt. Het eerste is een handeling die de wet voorbehoudt aan degene die meldt; het tweede hoort niet thuis in een integratiekoppeling.
Het dossier, van begin tot eind
Cliënten, dossiers, bewijsstukken, screening, uiteindelijk begunstigden, risicobeoordeling, bewijsdossier, integriteitscontrole. Elke resource heeft een eigen scope: uw sleutel opent alleen wat u eraan hebt meegegeven.
Journaal en aggregaten
De pKYC-gebeurtenissen van het kantoor — verlopen document, wijziging van uiteindelijk begunstigde, te beoordelen herscreening — en portefeuilletellers voor uw dashboard. Antwoord altijd begrensd, cursor stabiel.
Wat u schrijft, draagt een naam
Uploaden, screenen, kwalificeren: elke schrijfactie vereist een eigen scope en legt de operator vast. Een anonieme kwalificatie wordt geweigerd — de integratie legt een menselijke beslissing vast, zij neemt er zelf geen.
De API is ontworpen voor server-naar-server: een sleutel in code die naar de browser gaat, is een gepubliceerde sleutel. Laat een proxy aan serverzijde de sleutel bewaren, nooit de pagina.
Sleutels met scopes, één keer getoond, onmiddellijk intrekbaar.
- Formaat. Elke sleutel begint met
vgk_en wordt verstuurd alsAuthorization: Bearer vgk_…. Het geheim wordt alleen bij de aanmaak getoond: wij bewaren niets anders dan de SHA-256-digest ervan. - Scopes. Een sleutel draagt alleen de scopes die bij het aanmaken zijn aangevinkt: de algemene
lecture(lezen, de standaard) enecriture(schrijven), of fijnmazige scopes, per resource —clients:,dossiers:,pieces:,criblage:(inlectureofecriture),origine-fonds:lecture,journal:lecture.
De overerving volgt het achtervoegsel en werkt maar één kant op:lecturedekt elke*:lecture,ecritureelke*:ecriture; een fijnmazige scope opent niets buiten zichzelf.
Zes scopes vallen buiten dat paar en worden dus door geen enkele algemene sleutel geërfd:alertes:qualifier,embed:emettre,adversemedia:consulter,conformite:consulter,dispositif:consulter,integrite:consulter. Elk wordt afzonderlijk gedelegeerd, bij het aanmaken van de sleutel.
Een sleutel zonder de vereiste scope krijgt een 403 — zie #scopes. - Vervaldatum. Eén jaar na de aanmaak (zichtbaar in de console van het kantoor). Een verlopen sleutel krijgt een expliciete 401 — zie #cle-expiree.
Een sleutel kan ook vóór die datum niet langer worden aanvaard, wanneer de API niet meer in het abonnement van het kantoor zit. De stop valt dan ten minste 30 dagen na een eerste e-mail aan het kantoor, op de datum die een tweede e-mail noemt, ten minste 7 dagen vooraf verstuurd. Zodra die vaststaat, is deze datum zichtbaar in de console van het kantoor (veldcoupure_levanGET /connect/cles), en elk antwoord op een aanvaarde aanroep kondigt hem aan in de headerSunsettot hij is bereikt. Na die datum krijgt de aanroep de 401 van #authentification, met"motif": "fin_option_api"; zit de API weer in het abonnement, dan wordt de sleutel weer aanvaard, tot zijn eigen vervaldatum.
Een ingetrokken sleutel komt niet terug met de API. En wanneer het hele abonnement wordt opgeschort of afloopt, worden de sleutels onmiddellijk niet langer aanvaard, zonder deze termijn. - Limiet. 60 verzoeken/minuut per sleutel (per sleutel aanpasbaar). Een 429 draagt
Retry-Afteren de headersX-RateLimit-Limit / -Remaining / -Reset. - Intrekking. Onmiddellijk, vanuit de console. De resolutie verloopt via de digest: sleutels kunnen niet worden opgesomd.
Drie curl-aanroepen en u hebt alles gezien.
# Health + authenticatie met sleutel
curl -s https://vigilae.org/api/v1/sante \
-H "Authorization: Bearer vgk_your_key"
# Monitoringjournaal, vanaf het begin, in pagina's van 100
curl -s "https://vigilae.org/api/v1/evenements?depuisSeq=0&limite=100" \
-H "Authorization: Bearer vgk_your_key"
# Gebeurtenis 42 kwalificeren (schrijfscope)
curl -s -X POST https://vigilae.org/api/v1/evenements/42/qualifier \
-H "Authorization: Bearer vgk_your_key" \
-H "Content-Type: application/json" \
-d '{"statut":"qualifie","disposition":"traite"}'Paginering, in één regel
Geef depuisSeq mee (0 bij de eerste aanroep) en limite (begrensd op 500): het antwoord is gesorteerd op oplopende seq en geeft prochainSeq terug, om bij de volgende aanroep ongewijzigd terug te sturen. Een pagina korter dan limite betekent het einde van het journaal — prochainSeq blijft dan stabiel en dient als pollingcursor. Zonder depuisSeq krijgt u de weergave "meest recent eerst", begrensd tot 500.
De portefeuille wordt bevraagd op /api/v1/portefeuille/agregats — tellers, één antwoord, geen paginering.
Ondertekend, tijdgestempeld, minstens één keer bezorgd.
Ontvang het journaal in plaats van het te pollen: Vigilae bezorgt gebeurtenissen op uw URL, in volgorde, in batches van hoogstens 100. De bezorging is at-least-once — de cursor schuift alleen op bij uw 2xx, batch per batch — en idempotentie loopt via seq: verwerk elke sequentie precies één keer (#idempotence).
De handtekening verifiëren
Elke bezorging draagt de header x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body). Herbereken v1 op basis van de ruwe body zoals ontvangen, en verwerp elke tijdstempel t voorbij 5 min: dat is de anti-replay. Tijdens een rotatie van het geheim draagt de header één v1 per nog geldig geheim (24 u overlap): aanvaard zodra er één overeenstemt.
// Node — verificatie van de handtekening (zonder dependency)
import { createHmac, timingSafeEqual } from 'node:crypto';
export function signatureValid(header, rawBody, secrets, toleranceMs = 5 * 60 * 1000) {
const t = Number((/(?:^|,)t=(\d+)/.exec(header) || [])[1]);
if (!t || Math.abs(Date.now() - t * 1000) > toleranceMs) return false; // anti-replay
const received = [...header.matchAll(/v1=([0-9a-f]{64})/g)].map((m) => m[1]);
return [].concat(secrets).some((secret) => {
const expected = createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');
return received.some((r) => r.length === expected.length
&& timingSafeEqual(Buffer.from(r), Buffer.from(expected)));
});
}# Python — dezelfde verificatie
import hmac, hashlib, re, time
def signature_valid(header: str, raw_body: bytes, secrets, tolerance_s: int = 300) -> bool:
m = re.search(r"(?:^|,)t=(\d+)", header)
if not m or abs(time.time() - int(m.group(1))) > tolerance_s:
return False # anti-replay
received = re.findall(r"v1=([0-9a-f]{64})", header)
for secret in secrets:
expected = hmac.new(secret.encode(), m.group(1).encode() + b"." + raw_body,
hashlib.sha256).hexdigest()
if any(hmac.compare_digest(expected, r) for r in received):
return True
return FalseOvergangsregeling: het oude formaat sha256=HMAC(body) wordt nog uitgezonden op x-vigilae-signature-legacy voor reeds bestaande ontvangers; de verwijdering ervan is gepland met webhooks v2. Nieuwe ontvangers verifiëren het tijdgestempelde schema hierboven, niet het oude.
De rotatie wordt gestart vanuit de console (POST /connect/webhook/rotation aan de applicatiekant): gedurende 24 u ondertekent het oude geheim nog — tijd om aan uw kant het nieuwe uit te rollen zonder venster van uitval.
Waakzaamheidsstatus, in uw schermen.
Uw software maakt de dossiers al aan via de API; widgets voegen het ontbrekende oppervlak toe: de waakzaamheidsstatus van een dossier tonen in uw cliëntfiche, zonder een compliance-interface te herbouwen. Het proces verloopt in drie stappen — uw server geeft een kort token uit, de teruggegeven URL komt in een iframe terecht, de widget toont. Meer doet hij niet: geen beslissing, geen kwalificatie, geen enkele schrijfactie loopt via een widget. De klik opent de Vigilae-applicatie, waar een geïdentificeerde mens handelt.
1. Het token uitgeven — serverzijde, nooit in de pagina
De vgk_-sleutel raakt de browser nooit. Uw server roept de mint aan met het toegewezen scope embed:emettre (aangevinkt bij het aanmaken van de sleutel, nooit overgeërfd) en alleen het korte token daalt af naar de pagina: vijftien minuten standaard, begrensd tussen 5 en 60, gebonden aan één dossier, één component, één opgegeven origin. Het reist in het URL-fragment — het bereikt noch onze logs, noch de uwe.
# Een token voor de Compliance Button, label gekozen uit de catalogus
curl -s -X POST https://vigilae.org/api/v1/embed/jetons \
-H "Authorization: Bearer vgk_your_key" \
-H "Content-Type: application/json" \
-d '{"dossier_id":"D123","composant":"bouton",
"audience":"https://your-software.example","libelle":"controler_client"}'
# 201 -> { "jeton": "…", "expire_le": "…",
# "url": "https://vigilae.org/embarque/bouton?c=…#…" }2. De iframe plaatsen — de launcher, in tien regels
De launcher vigilae-embed.js maakt de sandboxed iframe aan, voert de handshake uit en volgt de grootte van de widget (begrensd — de iframe dicteert nooit haar hoogte aan uw pagina). Wat CSP betreft, opent uw pagina één enkele directive: frame-src https://vigilae.org. Geen inline script vereist, geen dependency. Een met de hand geschreven iframe werkt net zo goed.
<script src="https://vigilae.org/embarque/vigilae-embed.js" defer></script>
<div id="vigilance"></div>// In uw script: de url komt van UW server, die de mint heeft aangeroepen
var widget = VigilaeEmbed.monter({
conteneur: 'vigilance',
url: urlReturnedByTheMint,
renouvelerJeton: function () { // bij verval: opnieuw uitgeven, serverzijde
return fetch('/my-server/vigilae-token').then(function (r) { return r.text(); });
},
});
// widget.rafraichir(token) stuurt een vers token; widget.demonter() verwijdert alles.3. De Compliance Button: uw label, onze status
Het knoplabel komt uit een gesloten catalogus — nooit vrije tekst op een oppervlak dat over waakzaamheid gaat. De shell toont dat label alleen in het Frans of het Engels (parameter ?lang=), nog niet in uw taal; de lijst hieronder geeft de betekenis:
controler_client— "Deze cliënt controleren" (standaard)lancer_vigilance— "Cliëntenonderzoek starten"verifier_be— "Uiteindelijk begunstigden controleren"preparer_dossier— "Antiwitwasdossier voorbereiden"
De statusindicator toont echter een status die Vigilae berekent: a_jour (groen — screening en score actueel), a_revoir (amber — screening of score verouderd, of de bron mislukte bij de laatste run), alerte (rood — minstens één alert te beoordelen), inconnu (grijs — dossier nooit gescreend). Het label is configureerbaar, de semantiek nooit: de kleur is aan de status gebonden binnen de shell zelf, die elke poging tot overschrijven via postMessage negeert. Een dossier in alert toont een alert, ongeacht de opmaak.
Het postMessage-contract, volledig
De widget zendt vigilae:pret, vigilae:taille (automatische aanpassing), vigilae:expire (opnieuw uitgeven, serverzijde, en dan vigilae:jeton posten) en vigilae:ouvrir uit. Nooit een naam, een risico of een alert in een bericht: uw software heeft al alles via de server-naar-server-API, en dit kanaal wordt geen tweede.
frame-ancestors-CSP van de shell aanstuurt. De beheerder geeft dit rechtstreeks zelf op in Vigilae, op het scherm "Integraties & beveiliging": ten hoogste tien https://-origins, expliciete host, nooit een jokerteken; de componenten die hij inschakelt; en een massale intrekking die in één klap alle al uitgegeven tokens ongeldig maakt. http://localhost is alleen toegestaan op een proefkantoor — schrijf naar contact@vigilae.org (onderwerp "Ingebedde widgets") om er één te laten openen voor de duur van uw integratie. Geen origin opgegeven: de mint weigert met een 400. Een instantie waarvan de origin-opslag niet is aangesloten: een expliciete 501 — zie #embed-indisponible.Sandbox: op aanvraag.
Elke foutklasse van de API heeft een stabiel adres in de foutenreferentie: #authentification, #scopes, #cloisonnement, #debit, #signature… De foutantwoorden van de API zullen naar deze ankers verwijzen.
De API legt geen meldingen van ongebruikelijke transacties en geen letterlijke cliëntinhoud bloot, door haar opzet (art. L.561-18 van het Franse CMF). Geen enkele waakzaamheidsbeslissing wordt door de API genomen: zij legt gebeurtenissen bloot en kwalificeert ze; de professional beslist.