API, който можете да прочетете, преди да подпишете.
Спецификацията е публична, подписът на webhook-а може да бъде проверен в десет реда от ваша страна. Тази страница документира това, което API-ят излага днес — нищо повече, и това е съзнателно: което не е доставено, не е документирано.
- OpenAPI спецификация, четима без ключ и без акаунт
- Никога уведомление за съмнителна операция, никога дословно клиентско съдържание
- Подписани webhooks, проверими извън Vigilae
Сервира се от самия API: договорът, който четете, е този, който работи.
Целият път на досието — и две изключения, които няма да се променят.
Вашият софтуер може да води досие от край до край: да създаде клиента, да открие досието, да качи документите, да стартира проверката по списъци, да декларира действителните собственици, да прочете оценката на риска и да изтегли доказателственото досие. Две неща никога няма да минат оттам и това не е ограничение на абонамента: никакво съобщение за съмнителна сделка и никакви дословни изказвания на вашия клиент. Първото е действие, което законът запазва за лицето, което подава съобщението; второто няма място в интеграционен канал.
Досието — от край до край
Клиенти, досиета, удостоверителни документи, проверка по списъци, действителни собственици, оценка на риска, доказателствено досие, контрол за цялост. Всеки ресурс си има обхват: вашият ключ отваря само това, което сте му дали.
Дневник и обобщени показатели
Събитията pKYC на кантората — изтекъл документ, промяна на действителен собственик, повторна проверка за обработване — и броячи за портфейла за вашето табло. Отговорът е винаги ограничен, курсорът — стабилен.
Това, което записвате, носи име
Качване, проверка, квалифициране: всяко записване изисква своя обхват и отбелязва оператора. Анонимна квалификация се отхвърля — интеграцията записва човешко решение, но не произвежда нито едно.
API-ят е замислен сървър към сървър: ключ в код, доставен до браузъра, е публикуван ключ. Нека ключа държи прокси от страната на сървъра, никога страницата.
Ключове с ограничен обхват, показвани веднъж, отменими незабавно.
- Формат. Всеки ключ започва с
vgk_и се изпраща катоAuthorization: Bearer vgk_…. Тайната се показва само при създаването: ние пазим единствено нейния SHA-256 отпечатък. - Обхвати. Ключът носи само обхватите, отметнати при създаването му: общите
lecture(четене, по подразбиране) иecriture(запис) или фини обхвати, ресурс по ресурс —clients:,dossiers:,pieces:,criblage:(вlectureилиecriture),origine-fonds:lecture,journal:lecture.
Наследяването е по суфикс и върви само в едната посока:lectureпокрива всяко*:lecture, аecriture— всяко*:ecriture; финият обхват не отваря нищо извън себе си.
Шест обхвата излизат извън тази двойка и затова не се наследяват от никакъв общ ключ:alertes:qualifier,embed:emettre,adversemedia:consulter,conformite:consulter,dispositif:consulter,integrite:consulter. Всеки от тях се делегира поотделно, при създаването на ключа.
Ключ без изисквания обхват получава 403 — вж. #scopes. - Изтичане. Една година след създаването (видимо в конзолата на кантората). Изтекъл ключ получава изричен 401 — вж. #cle-expiree.
Ключ може да престане да бъде приеман и преди тази дата, когато API вече не е част от абонамента на кантората. Прекратяването настъпва тогава поне 30 дни след първи имейл до кантората, на датата, посочена във втори имейл, изпратен поне 7 дни предварително. Щом бъде определена, тази дата се вижда в конзолата на кантората (полетоcoupure_leнаGET /connect/cles), а всеки отговор на приета заявка я обявява в заглавкатаSunset, докато настъпи. След тази дата заявката получава 401, описан в #authentification, с"motif": "fin_option_api"; ако API отново бъде включен в абонамента, ключът отново се приема, до изтичането на собствения му срок.
Отменен ключ не се връща заедно с API. А когато целият абонамент бъде спрян или приключи, ключовете престават да бъдат приемани незабавно, без този срок. - Дебит. 60 заявки/минута на ключ (променимо за всеки ключ). Отговорът 429 носи
Retry-Afterи заглавкитеX-RateLimit-Limit / -Remaining / -Reset. - Отмяна. Незабавна, от конзолата. Разпознаването е по отпечатък: ключовете не могат да бъдат изброявани.
Три curl заявки и сте видели всичко.
# Здраве + удостоверяване на ключа
curl -s https://vigilae.org/api/v1/sante \
-H "Authorization: Bearer vgk_your_key"
# Журнал за наблюдение, от началото, на страници по 100
curl -s "https://vigilae.org/api/v1/evenements?depuisSeq=0&limite=100" \
-H "Authorization: Bearer vgk_your_key"
# Квалифициране на събитие 42 (обхват за запис)
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"}'Странициране, в едно правило
Подайте depuisSeq (0 при първата заявка) и limite (ограничено до 500): отговорът е сортиран по възходящ seq и връща prochainSeq, който подавате обратно без промяна при следващата заявка. Страница, по-къса от limite, означава край на журнала — тогава prochainSeq остава стабилен и служи като курсор за периодично допитване. Без depuisSeq получавате изгледа „най-новите първи“, ограничен до 500.
Портфейлът се заявява на /api/v1/portefeuille/agregats — броячи, един отговор, без странициране.
Подписани, с времеви печат, доставяни поне веднъж.
Вместо да допитвате журнала, получавайте го: Vigilae доставя събитията на вашия URL, по ред, на партиди от най-много 100. Доставката е at-least-once — курсорът напредва само при ваш 2xx, партида по партида — а идемпотентността е по seq: обработвайте всяка последователност точно веднъж (#idempotence).
Проверка на подписа
Всяка доставка носи заглавката x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body). Изчислете отново v1 от суровото получено тяло и отхвърляйте всеки времеви печат t отвъд 5 мин: това е защитата срещу повторение. По време на ротация на тайната заглавката носи по един v1 за всяка все още валидна тайна (24 ч припокриване): приемете, ако който и да е от тях съвпада.
// Node — проверка на подписа (без зависимости)
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; // защита срещу повторение
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 — същата проверка
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 # защита срещу повторение
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Преходно: старият формат sha256=HMAC(body) все още се излъчва в x-vigilae-signature-legacy за вече работещите приемници; премахването му е планирано с webhooks v2. Новите приемници проверяват схемата с времеви печат по-горе, а не старата.
Ротацията се задейства от конзолата (POST /connect/webhook/rotation от страна на приложението): в продължение на 24 ч старата тайна продължава да подписва — време да разположите новата от ваша страна без прозорец на отказ.
Състоянието на бдителността, във вашите екрани.
Вашият софтуер вече създава преписките през API-я; уиджетите му дават повърхността, която липсваше: показване на състоянието на бдителност на преписка вътре във вашия клиентски картон, без да изграждате наново интерфейс за съответствие. Потокът минава в три стъпки — вашият сървър издава краткотраен токен, върнатият URL адрес влиза в iframe, уиджетът показва. Той само показва: никакво решение, никаква квалификация, никакво записване никога не минава през уиджет. Кликването отваря приложението Vigilae, където действа идентифициран човек.
1. Издаване на токена — от страна на сървъра, никога в страницата
Ключът vgk_ никога не докосва браузъра. Вашият сървър извиква mint със специалния обхват embed:emettre (отбелязан при създаването на ключа, никога не се наследява) и само краткият токен слиза до страницата: петнадесет минути по подразбиране, ограничен 5-60, обвързан с една преписка, един компонент, един деклариран произход. Той пътува във фрагмента на URL адреса — не достига нито до нашите логове, нито до вашите.
# Токен за Compliance Button, етикет, избран от каталога
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. Поставяне на iframe — стартовият скрипт, в десет реда
Стартовият скрипт vigilae-embed.js създава sandbox iframe, извършва ръкостискането и следи размера на уиджета (ограничен — iframe никога не диктува височината си на вашата страница). По отношение на CSP вашата страница отваря само една директива: frame-src https://vigilae.org. Не се изисква inline скрипт, никаква зависимост. Ръчно написан iframe работи също толкова добре.
<script src="https://vigilae.org/embarque/vigilae-embed.js" defer></script>
<div id="vigilance"></div>// Във вашия скрипт: url адресът идва от ВАШИЯ сървър, който извика mint
var widget = VigilaeEmbed.monter({
conteneur: 'vigilance',
url: urlReturnedByTheMint,
renouvelerJeton: function () { // при изтичане: подновете токена от страна на сървъра
return fetch('/my-server/vigilae-token').then(function (r) { return r.text(); });
},
});
// widget.rafraichir(token) подава свеж токен; widget.demonter() премахва всичко.3. Compliance Button: вашият етикет, нашето състояние
Етикетът на бутона се избира от затворен каталог — никога свободен текст върху повърхност, която говори за бдителност — шелът обаче ги показва само на френски или английски (параметър ?lang=), все още не на вашия език; списъкът по-долу дава смисъла им:
controler_client— „Проверете този клиент“ (по подразбиране)lancer_vigilance— „Започнете надлежната проверка“verifier_be— „Проверете действителните собственици“preparer_dossier— „Подгответе преписката по ПИП/ФТ“
Индикаторът, от своя страна, показва състояние, изчислено от Vigilae: a_jour (зелено — проверката и оценката са актуални), a_revoir (кехлибарено — проверката или оценката са остарели, или източникът е отказал при последното изпълнение), alerte (червено — поне един сигнал за преглед), inconnu (сиво — преписка, никога не проверявана). Етикетът се конфигурира, семантиката — никога: цветът е обвързан със състоянието вътре в самия shell, който игнорира всеки опит за подмяна чрез postMessage. Преписка със сигнал показва сигнал, независимо от оформлението.
Договорът postMessage, изцяло
Уиджетът излъчва vigilae:pret, vigilae:taille (автоматично оразмеряване), vigilae:expire (издайте нов токен от страна на сървъра, след което изпратете vigilae:jeton) и vigilae:ouvrir. Никога име, риск или сигнал в съобщение: вашият софтуер вече разполага с всичко чрез API-я от сървър към сървър, и този канал няма да стане втори такъв.
frame-ancestors на shell-а. Администраторът го декларира директно във Vigilae, в екран „Интеграции и сигурност“: най-много десет произхода https://, изричен хост, никога заместващ знак; компонентите, които той активира; и масово отнемане, което с един жест убива всички вече издадени токени. http://localhost е допустим само за пробна кантора — пишете на contact@vigilae.org (тема „Вградени уиджети“) да ви отворят такава за времето на вашата интеграция. Без деклариран произход: mint отказва с 400. Инстанция, чието хранилище за произходи не е свързано: изричен 501 — вж. #embed-indisponible.Sandbox: при поискване.
Всеки клас API грешки има стабилен адрес в справочника на грешките: #authentification, #scopes, #cloisonnement, #debit, #signature… Отговорите за грешка на API-я ще сочат към тези котви.
API-ят не излага нито уведомления за съмнителни операции, нито дословно клиентско съдържание, по конструкция (art. L.561-18 от френския CMF). Никакво решение по надлежния контрол не се взема от API-я: той излага и квалифицира събития; професионалистът решава.