Vigilae Connect

Ένα API που το διαβάζετε πριν υπογράψετε.

Η προδιαγραφή είναι δημόσια, η υπογραφή των webhooks επαληθεύεται σε δέκα γραμμές από την πλευρά σας. Αυτή η σελίδα τεκμηριώνει ό,τι εκθέτει το API σήμερα — τίποτα περισσότερο, και αυτό είναι εσκεμμένο: ό,τι δεν έχει παραδοθεί δεν τεκμηριώνεται.

  • Προδιαγραφή OpenAPI αναγνώσιμη χωρίς κλειδί ή λογαριασμό
  • Ποτέ αναφορά ύποπτης συναλλαγής, ποτέ αυτούσια δεδομένα πελατών
  • Υπογεγραμμένα webhooks, επαληθεύσιμα εκτός Vigilae

Σερβίρεται από το ίδιο το API: η σύμβαση που διαβάζετε είναι αυτή που εκτελείται.

Η περίμετρος

Ολόκληρη η διαδρομή του φακέλου — και δύο εξαιρέσεις που δεν πρόκειται να αλλάξουν.

Το λογισμικό σας μπορεί να διεκπεραιώσει έναν φάκελο από άκρη σε άκρη: να δημιουργήσει τον πελάτη, να ανοίξει τον φάκελο, να καταθέσει τα έγγραφα, να ξεκινήσει τη διαλογή, να δηλώσει τους πραγματικούς δικαιούχους, να διαβάσει τη διαβάθμιση κινδύνου και να παραλάβει τον φάκελο αποδείξεων. Δύο πράγματα δεν θα περάσουν ποτέ από εκεί, και δεν πρόκειται για περιορισμό συνδρομής: καμία αναφορά ύποπτης συναλλαγής και καμία αυτούσια δήλωση του πελάτη σας. Η πρώτη είναι πράξη που ο νόμος επιφυλάσσει στο πρόσωπο που υποβάλλει την αναφορά· η δεύτερη δεν έχει καμία θέση σε έναν δίαυλο ενσωμάτωσης.

Ο φάκελος, από άκρη σε άκρη

Πελάτες, φάκελοι, δικαιολογητικά έγγραφα, διαλογή, πραγματικοί δικαιούχοι, διαβάθμιση κινδύνου, φάκελος αποδείξεων, έλεγχος ακεραιότητας. Κάθε πόρος έχει το δικό του πεδίο πρόσβασης: το κλειδί σας ανοίγει μόνο ό,τι του δώσατε.

Ημερολόγιο και συγκεντρωτικά στοιχεία

Τα συμβάντα pKYC του γραφείου — έγγραφο που έληξε, αλλαγή πραγματικού δικαιούχου, επαναδιαλογή προς διεκπεραίωση — και μετρητές χαρτοφυλακίου για τον δικό σας πίνακα ελέγχου. Η απόκριση είναι πάντα οριοθετημένη, ο δείκτης σταθερός.

Ό,τι γράφετε φέρει όνομα

Κατάθεση, διαλογή, αξιολόγηση: κάθε εγγραφή απαιτεί το πεδίο πρόσβασής της και καταγράφει τον χειριστή. Μια ανώνυμη αξιολόγηση απορρίπτεται — η ενσωμάτωση καταγράφει μια ανθρώπινη απόφαση, δεν παράγει καμία.

Το API είναι σχεδιασμένο server-to-server: ένα κλειδί σε κώδικα που φτάνει στον browser είναι δημοσιευμένο κλειδί. Αναθέστε το κλειδί σε server-side proxy, ποτέ στη σελίδα.

Κλειδιά

Κλειδιά με εμβέλειες, εμφανίζονται μία φορά, ανακαλούνται αμέσως.

  • Μορφή. Κάθε κλειδί ξεκινά με vgk_ και αποστέλλεται ως Authorization: Bearer vgk_…. Το μυστικό εμφανίζεται μόνο κατά τη δημιουργία: δεν κρατάμε τίποτα πέρα από τη σύνοψή του σε SHA-256.
  • Εμβέλειες (scopes). Ένα κλειδί φέρει μόνο τις εμβέλειες που επιλέχθηκαν κατά τη δημιουργία του: τις γενικές 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. Εκχωρούνται μία προς μία, κατά τη δημιουργία του κλειδιού.
    Ένα κλειδί χωρίς το απαιτούμενο scope λαμβάνει 403 — βλ. #scopes.
  • Λήξη. Ένα έτος μετά τη δημιουργία (ορατή στην κονσόλα του γραφείου). Ένα ληγμένο κλειδί λαμβάνει ρητό 401 — βλ. #cle-expiree.
    Ένα κλειδί μπορεί επίσης να πάψει να γίνεται δεκτό πριν από αυτή την ημερομηνία, όταν το API δεν αποτελεί πλέον μέρος της συνδρομής του γραφείου. Η παύση έρχεται τότε τουλάχιστον 30 ημέρες μετά από ένα πρώτο e-mail προς το γραφείο, στην ημερομηνία που αναφέρει ένα δεύτερο e-mail, σταλμένο τουλάχιστον 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 (scope εγγραφής) 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 μένει τότε σταθερό και χρησιμεύει ως δρομέας polling. Χωρίς depuisSeq, λαμβάνετε την προβολή «τα πιο πρόσφατα πρώτα», με όριο τα 500.

Το χαρτοφυλάκιο ερωτάται στο /api/v1/portefeuille/agregats — μετρητές, μία απόκριση, χωρίς σελιδοποίηση.

Webhooks

Υπογεγραμμένα, χρονοσφραγισμένα, παραδιδόμενα τουλάχιστον μία φορά.

Αντί να κάνετε polling στο ημερολόγιο, λάβετέ το: η Vigilae παραδίδει τα συμβάντα στο URL σας, με τη σειρά, σε παρτίδες έως 100. Η παράδοση είναι at-least-once — ο δρομέας προχωρά μόνο με το δικό σας 2xx, παρτίδα προς παρτίδα — και η ταυτοδυναμία βασίζεται στο seq: επεξεργαστείτε κάθε ακολουθία ακριβώς μία φορά (#idempotence).

Επαλήθευση της υπογραφής

Κάθε παράδοση φέρει την κεφαλίδα x-vigilae-signature: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body). Επανυπολογίστε το v1 από το ακατέργαστο σώμα που λάβατε, και απορρίψτε κάθε χρονοσφραγίδα t πέραν των 5 λεπτών: αυτή είναι η προστασία anti-replay. Κατά τη διάρκεια εναλλαγής μυστικού, η κεφαλίδα φέρει ένα 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; // 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 — η ίδια επαλήθευση 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 False

Μεταβατικό: η παλαιά μορφή sha256=HMAC(body) εκπέμπεται ακόμη στην κεφαλίδα x-vigilae-signature-legacy για τους δέκτες που είναι ήδη σε λειτουργία· η κατάργησή της προγραμματίζεται με τα webhooks v2. Οι νέοι δέκτες επαληθεύουν το χρονοσφραγισμένο σχήμα παραπάνω, όχι το παλαιό.

Η εναλλαγή ενεργοποιείται από την κονσόλα (POST /connect/webhook/rotation από την πλευρά της εφαρμογής): για 24 ώρες το παλαιό μυστικό εξακολουθεί να υπογράφει — χρόνος για να αναπτύξετε το νέο από την πλευρά σας χωρίς παράθυρο αστοχίας.

Ενσωματωμένα widgets

Η κατάσταση επαγρύπνησης, μέσα στις οθόνες σας.

Το λογισμικό σας δημιουργεί ήδη τους φακέλους μέσω του API· τα widgets του δίνουν την επιφάνεια που έλειπε: να δείχνει την κατάσταση επαγρύπνησης ενός φακέλου μέσα στην καρτέλα πελάτη σας, χωρίς να χτίζετε εκ νέου μια διεπαφή συμμόρφωσης. Η ροή κρατά τρία βήματα — ο διακομιστής σας εκδίδει ένα βραχύβιο διακριτικό, η διεύθυνση URL που επιστρέφεται τοποθετείται σε ένα iframe, το widget εμφανίζει. Δεν κάνει τίποτε άλλο πέρα από το να εμφανίζει: καμία απόφαση, κανένας χαρακτηρισμός, καμία εγγραφή δεν περνά ποτέ μέσα από ένα widget. Το κλικ ανοίγει την εφαρμογή Vigilae, όπου ενεργεί ένας ταυτοποιημένος άνθρωπος.

1. Εκδώστε το διακριτικό — από την πλευρά του διακομιστή, ποτέ μέσα στη σελίδα

Το κλειδί vgk_ δεν αγγίζει ποτέ τον browser. Ο διακομιστής σας καλεί το mint με το αποκλειστικό scope embed:emettre (επιλεγμένο κατά τη δημιουργία του κλειδιού, ποτέ κληρονομούμενο) και μόνο το σύντομο διακριτικό κατεβαίνει στη σελίδα: δεκαπέντε λεπτά εξ ορισμού, με όριο 5-60, δεμένο σε έναν φάκελο, ένα στοιχείο, μία δηλωμένη προέλευση. Ταξιδεύει μέσα στο fragment της 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 δημιουργεί το iframe σε sandbox, εκτελεί το handshake και ακολουθεί το μέγεθος του widget (με όριο — το iframe δεν υπαγορεύει ποτέ το ύψος του στη σελίδα σας). Ως προς την CSP, η σελίδα σας ανοίγει μία και μόνη οδηγία: frame-src https://vigilae.org. Δεν απαιτείται inline script, καμία εξάρτηση. Ένα χειρόγραφο iframe λειτουργεί εξίσου καλά.

<script src="https://vigilae.org/embarque/vigilae-embed.js" defer></script> <div id="vigilance"></div>
// Στο script σας: το 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: η ετικέτα σας, η κατάστασή μας

Η ετικέτα του κουμπιού επιλέγεται από κλειστό κατάλογο — ποτέ ελεύθερο κείμενο σε μια επιφάνεια που μιλά για επαγρύπνηση· το ενσωματωμένο shell εμφανίζει τις ετικέτες μόνο στα γαλλικά ή στα αγγλικά (παράμετρος ?lang=), όχι ακόμη στη γλώσσα σας — η παρακάτω λίστα δίνει το νόημά τους:

  • controler_client — «Έλεγχος αυτού του πελάτη» (προεπιλογή)
  • lancer_vigilance — «Έναρξη επαγρύπνησης»
  • verifier_be — «Έλεγχος πραγματικών δικαιούχων»
  • preparer_dossier — «Προετοιμασία του φακέλου ΞΧ/ΧΤ»

Η κουκκίδα κατάστασης, όμως, αποδίδει μια κατάσταση υπολογισμένη από το Vigilae: a_jour (πράσινο — screening και βαθμολόγηση ενημερωμένα), a_revoir (πορτοκαλί — screening ή βαθμολόγηση ξεπερασμένα, ή πηγή που απέτυχε στην τελευταία εκτέλεση), alerte (κόκκινο — τουλάχιστον μία ειδοποίηση προς εξέταση), inconnu (γκρι — φάκελος που δεν υποβλήθηκε ποτέ σε screening). Η ετικέτα ρυθμίζεται, η σημασιολογία ποτέ: το χρώμα είναι δεμένο με την κατάσταση μέσα στο ίδιο το shell, το οποίο αγνοεί κάθε απόπειρα να το παρακάμψει μέσω postMessage. Ένας φάκελος σε ειδοποίηση εμφανίζεται σε ειδοποίηση, όποιο κι αν είναι η μορφοποίηση.

Η σύμβαση postMessage, εξ ολοκλήρου

Το widget εκπέμπει τα vigilae:pret, vigilae:taille (αυτόματη προσαρμογή μεγέθους), vigilae:expire (επανέκδοση στον διακομιστή, έπειτα αποστολή του vigilae:jeton) και vigilae:ouvrir. Ποτέ όνομα, κίνδυνος ή ειδοποίηση μέσα σε μήνυμα: το λογισμικό σας έχει ήδη τα πάντα μέσω του server-to-server API, και αυτό το κανάλι δεν πρόκειται να γίνει ένα δεύτερο κανάλι.

Δήλωση προελεύσεων: από τον διαχειριστή του γραφείου σας. Ένα διακριτικό embed είναι δεμένο σε μια δηλωμένη προέλευση του γραφείου σας — αυτή είναι που οδηγεί την CSP frame-ancestors του shell. Ο διαχειριστής τη δηλώνει απευθείας μέσα στο Vigilae, στην οθόνη «Ενσωματώσεις & ασφάλεια»: το πολύ δέκα προελεύσεις https://, με ρητό όνομα διακομιστή, χωρίς μπαλαντέρ· τα στοιχεία που ενεργοποιεί· και μια μαζική ανάκληση που ακυρώνει με μία κίνηση όλα τα διακριτικά που έχουν ήδη εκδοθεί. Το http://localhost επιτρέπεται μόνο σε γραφείο sandbox — γράψτε στο contact@vigilae.org (θέμα «Embedded widgets») για να σας ανοίξουν ένα τέτοιο για όσο διαρκεί η ενσωμάτωσή σας. Καμία προέλευση δηλωμένη: το mint αρνείται με 400. Εγκατάσταση της οποίας η αποθήκευση προελεύσεων δεν είναι συνδεδεμένη: ρητό 501 — βλ. #embed-indisponible.
Περιβάλλον δοκιμών

Sandbox: κατόπιν αιτήματος.

Δεν υπάρχει ακόμη sandbox αυτόματης πρόσβασης — προτιμούμε να σας το πούμε εδώ παρά να το ανακαλύψετε μόνοι σας. Γράψτε στο contact@vigilae.org (θέμα «API access»): ανοίγουμε ένα δοκιμαστικό γραφείο με πλασματικά δεδομένα για όσο διαρκεί η ενσωμάτωσή σας, και παραμένουμε διαθέσιμοι όσο αυτή προχωρά.

Κάθε κατηγορία σφάλματος του API έχει σταθερή διεύθυνση στην αναφορά σφαλμάτων: #authentification, #scopes, #cloisonnement, #debit, #signature… Οι αποκρίσεις σφάλματος του API θα παραπέμπουν σε αυτές τις άγκυρες.

Το API δεν εκθέτει ούτε αναφορές ύποπτων συναλλαγών ούτε αυτούσια δεδομένα πελατών, εκ κατασκευής (άρθ. L.561-18 του γαλλικού CMF). Καμία απόφαση επαγρύπνησης δεν λαμβάνεται από το API: εκθέτει και χαρακτηρίζει συμβάντα· ο επαγγελματίας αποφασίζει.