Vigilae Connect

API, které si přečtete dřív, než podepíšete.

Specifikace je veřejná, podpis webhooku lze na vaší straně ověřit na deset řádků. Tato stránka dokumentuje, co API vystavuje dnes — nic víc, a je to záměr: co není dodáno, není zdokumentováno.

  • Specifikace OpenAPI čitelná bez klíče i bez účtu
  • Nikdy oznámení podezřelého obchodu, nikdy doslovný klientský obsah
  • Podepsané webhooky, ověřitelné mimo Vigilae

Servíruje ji samo API: kontrakt, který čtete, je ten, který běží.

Rozsah

Celý průběh spisu a dvě vyloučení, která se nezmění.

Váš software může vést spis od začátku do konce: založit klienta, otevřít spis, vložit doklady, spustit prověření, ohlásit skutečné majitele, přečíst klasifikaci rizika a vyzvednout důkazní spis. Dvě věci tudy nikdy neprojdou, a není to omezení tarifu: žádné oznámení podezřelého obchodu a žádný doslovný obsah od vašeho klienta. První je úkon, který zákon vyhrazuje osobě podávající oznámení; druhý nemá v integračním kanálu co dělat.

Spis od začátku do konce

Klienti, spisy, podkladové doklady, prověřování, skuteční majitelé, klasifikace rizika, důkazní spis, kontrola integrity. Každý zdroj má svůj scope: váš klíč otevírá jen to, co jste mu dali.

Deník a agregáty

Události pKYC kanceláře — prošlý doklad, změna skutečného majitele, opětovné prověření k vyřízení — a čítače portfolia pro váš dashboard. Odpověď je vždy omezená, kurzor stabilní.

Co zapíšete, nese jméno

Vložit, prověřit, kvalifikovat: každý zápis vyžaduje svůj scope a eviduje operátora. Anonymní kvalifikace je odmítnuta — integrace zaznamenává lidské rozhodnutí, sama žádné nevytváří.

API je navrženo pro komunikaci server–server: klíč v kódu odeslaném do prohlížeče je zveřejněný klíč. Klíč ať drží proxy na straně serveru, nikdy stránka.

Klíče

Klíče s vymezenými scopes, zobrazené jednou, okamžitě odvolatelné.

  • Formát. Každý klíč začíná vgk_ a posílá se jako Authorization: Bearer vgk_…. Tajemství se zobrazuje pouze při vytvoření: neuchováváme nic než jeho otisk SHA-256.
  • Scopes. Klíč nese jen ty scopy, které byly zaškrtnuty při jeho vytvoření: obecné lecture (čtení, výchozí) a ecriture (zápis), nebo jemné scopy zdroj po zdroji — clients:, dossiers:, pieces:, criblage: (v lecture nebo ecriture), origine-fonds:lecture, journal:lecture.
    Dědičnost se řídí příponou a jde jen jedním směrem: lecture pokrývá každé *:lecture, ecriture každé *:ecriture; jemný scope neotevírá nic nad rámec sebe sama.
    Šest scopů z této dvojice vybočuje, a proto se nedědí ze žádného obecného klíče: alertes:qualifier, embed:emettre, adversemedia:consulter, conformite:consulter, dispositif:consulter, integrite:consulter. Každý se deleguje zvlášť, při vytvoření klíče.
    Klíč bez požadovaného scopu dostane 403 — viz #scopes.
  • Platnost. Jeden rok od vytvoření (viditelné v konzoli kanceláře). Prošlý klíč dostane explicitní 401 — viz #cle-expiree.
    Klíč může přestat být přijímán i před tímto datem, když API již není součástí předplatného kanceláře. Zastavení pak nastane nejméně 30 dní po prvním e-mailu kanceláři, k datu, které uvede druhý e-mail, odeslaný nejméně 7 dní předem. Jakmile je stanoveno, toto datum je vidět v konzoli kanceláře (pole coupure_le v GET /connect/cles) a každá odpověď na přijaté volání je oznamuje v hlavičce Sunset, dokud nenastane. Po tomto datu volání obdrží 401 popsaný v #authentification, s "motif": "fin_option_api"; pokud se API vrátí do předplatného, klíč je znovu přijímán, až do konce jeho vlastní platnosti.
    Odvolaný klíč se s API nevrací. A když je celé předplatné pozastaveno nebo skončí, klíče přestanou být přijímány okamžitě, bez této lhůty.
  • Limit. 60 požadavků/minutu na klíč (lze upravit pro jednotlivý klíč). Odpověď 429 nese Retry-After a hlavičky X-RateLimit-Limit / -Remaining / -Reset.
  • Odvolání. Okamžité, z konzole. Vyhledání probíhá podle otisku: klíče nelze enumerovat.
Rychlý start

Tři volání curl a viděli jste všechno.

# Stav služby + ověření klíče curl -s https://vigilae.org/api/v1/sante \ -H "Authorization: Bearer vgk_your_key" # Deník sledování, od začátku, po stránkách po 100 curl -s "https://vigilae.org/api/v1/evenements?depuisSeq=0&limite=100" \ -H "Authorization: Bearer vgk_your_key" # Kvalifikovat událost 42 (scope zápisu) 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"}'

Stránkování v jednom pravidle

Předejte depuisSeq (při prvním volání 0) a limite (strop 500): odpověď je seřazena vzestupně podle seq a vrací prochainSeq, který při dalším volání předáte beze změny. Stránka kratší než limite znamená konec deníku — prochainSeq pak zůstává stabilní a slouží jako kurzor pro polling. Bez depuisSeq dostanete pohled „nejnovější napřed“, omezený na 500.

Portfolio se dotazuje na /api/v1/portefeuille/agregats — čítače, jedna odpověď, žádné stránkování.

Webhooky

Podepsané, s časovým razítkem, doručené alespoň jednou.

Místo dotazování na deník jej přijímejte: Vigilae doručuje události na vaši URL, v pořadí, v dávkách po nejvýše 100. Doručení je at-least-once — kurzor se posouvá jen po vašem 2xx, dávku po dávce — a idempotence se řídí seq: každou sekvenci zpracujte právě jednou (#idempotence).

Ověření podpisu

Každé doručení nese hlavičku x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body). Přepočítejte v1 ze surového přijatého těla a odmítněte každé časové razítko t starší než 5 minut: to je ochrana proti replay útoku. Během rotace tajemství nese hlavička jedno v1 za každé dosud platné tajemství (překryv 24 hodin): přijměte, pokud kterékoli z nich odpovídá.

// Node — ověření podpisu (bez závislostí) 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; // ochrana proti 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 — stejné ověření 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 # ochrana proti 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 False

Přechodné: starý formát sha256=HMAC(body) se stále emituje v hlavičce x-vigilae-signature-legacy pro už zavedené příjemce; jeho odstranění je plánováno s webhooky v2. Noví příjemci ověřují výše uvedené schéma s časovým razítkem, ne to staré.

Rotace se spouští z konzole (POST /connect/webhook/rotation na straně aplikace): po 24 hodin staré tajemství stále podepisuje — čas na nasazení nového na vaší straně bez okna výpadku.

Vložené widgety

Stav obezřetnosti, přímo ve vašich obrazovkách.

Váš software už vytváří spisy přes API; widgety mu dávají plochu, která chyběla: zobrazit stav obezřetnosti spisu přímo ve vaší kartě klienta, bez stavby vlastního rozhraní pro soulad. Postup má tři kroky — váš server vydá krátkodobý token, vrácená URL se vloží do iframu, widget zobrazí. Nic víc nedělá: žádné rozhodnutí, žádná kvalifikace, žádný zápis widgetem nikdy neprojde. Klik otevře aplikaci Vigilae, kde jedná identifikovaná osoba.

1. Vydání tokenu — na straně serveru, nikdy ve stránce

Klíč vgk_ se nikdy nedotkne prohlížeče. Váš server volá vydání tokenu s vyhrazeným scopem embed:emettre (zaškrtnutým při vytvoření klíče, nikdy neděděným), a na stránku se dostává jen krátký token: patnáct minut ve výchozím nastavení, v mezích 5-60, vázaný na jeden spis, jednu komponentu, jeden deklarovaný origin. Cestuje ve fragmentu URL — nedosáhne ani našich logů, ani vašich.

# Token pro Compliance Button, popisek vybraný z katalogu 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. Vložení iframu — spouštěč, v deseti řádcích

Spouštěč vigilae-embed.js vytvoří sandboxovaný iframe, provede handshake a sleduje velikost widgetu (v mezích — iframe nikdy nediktuje svou výšku vaší stránce). Co se CSP týče, vaše stránka otevírá jedinou direktivu: frame-src https://vigilae.org. Není potřeba žádný inline skript, žádná závislost. Ručně napsaný iframe funguje stejně dobře.

<script src="https://vigilae.org/embarque/vigilae-embed.js" defer></script> <div id="vigilance"></div>
// Ve vašem skriptu: url pochází z VAŠEHO serveru, který zavolal vydání tokenu var widget = VigilaeEmbed.monter({ conteneur: 'vigilance', url: urlReturnedByTheMint, renouvelerJeton: function () { // při vypršení: nové vydání na straně serveru return fetch('/my-server/vigilae-token').then(function (r) { return r.text(); }); }, }); // widget.rafraichir(token) vloží nový token; widget.demonter() všechno odstraní.

3. Compliance Button: váš popisek, náš stav

Popisek tlačítka se vybírá z uzavřeného katalogu — nikdy volný text na ploše, která hovoří o obezřetnosti. Shell popisky zobrazuje francouzsky nebo anglicky (parametr ?lang=), zatím ne ve vaší řeči; seznam níže dává jen jejich smysl:

  • controler_client — „Zkontrolovat tohoto klienta“ (výchozí)
  • lancer_vigilance — „Spustit obezřetnost“
  • verifier_be — „Zkontrolovat skutečné majitele“
  • preparer_dossier — „Připravit AML spis“

Stavová tečka však vykresluje stav vypočtený Vigilae: a_jour (zelená — prověřování a klasifikace rizika aktuální), a_revoir (oranžová — prověřování nebo klasifikace rizika zastaralé, nebo zdroj při posledním běhu selhal), alerte (červená — alespoň jedno upozornění k posouzení), inconnu (šedá — spis nikdy neprověřen). Popisek se konfiguruje, sémantika nikdy: barva je vázána na stav přímo v shellu, který ignoruje jakýkoli pokus přepsat ji přes postMessage. Spis s upozorněním zobrazuje upozornění, ať je vzhled jakýkoli.

Kontrakt postMessage, v plném rozsahu

Widget emituje vigilae:pret, vigilae:taille (automatické přizpůsobení velikosti), vigilae:expire (nové vydání na straně serveru, poté odešlete vigilae:jeton) a vigilae:ouvrir. Nikdy jméno, riziko nebo upozornění uvnitř zprávy: váš software už má vše přes server-to-server API, a tento kanál se druhým nestane.

Deklarace originů: administrátorem kanceláře. Token vloženého widgetu je vázán na deklarovaný origin vaší kanceláře — právě ten řídí CSP frame-ancestors shellu. Administrátor jej deklaruje přímo ve Vigilae, na obrazovce „Integrace a zabezpečení“: nejvýše deset originů https://, výslovně uvedený host, nikdy zástupný znak; komponenty, které aktivuje; a hromadné odvolání, které jedním gestem zabije všechny už vydané tokeny. http://localhost je povolen jen na zkušební kanceláři — napište na contact@vigilae.org (předmět „Embedded widgets“) a otevřeme vám jednu na dobu vaší integrace. Žádný deklarovaný origin: vydání tokenu skončí chybou 400. Instance, jejíž úložiště originů není zapojeno: explicitní 501 — viz #embed-indisponible.
Testovací prostředí

Sandbox: na vyžádání.

Samoobslužný sandbox zatím neexistuje — raději vám to řekneme tady, než abyste na to přišli sami. Napište na contact@vigilae.org (předmět „API access“): otevřeme zkušební kancelář s fiktivními daty na dobu vaší integrace a zůstáváme na příjmu, dokud postupuje.

Každá třída chyb API má stabilní adresu v referenčním přehledu chyb: #authentification, #scopes, #cloisonnement, #debit, #signature… Chybové odpovědi API budou na tyto kotvy odkazovat.

API nevystavuje oznámení podezřelého obchodu ani doslovný klientský obsah, už z konstrukce (čl. L.561-18 francouzského CMF). Žádné rozhodnutí v rámci obezřetnosti nečiní API: vystavuje a kvalifikuje události; rozhoduje profesionál.