Définir un payload schema qui survit à la réalité
La première règle, versionner dès le jour 1
Le payload doit être versionné explicitement. Pas “on changera plus tard”. Plus tard arrive toujours pendant un comité de risque.
Un schéma raisonnable commence par des champs d’enveloppe :
event_id
event_type
schema_version
occurred_at
sent_at
source_system
delivery_attempt
Puis des blocs métiers :
filing
issuer
insider
transaction
instrument
economics
compliance_flags
links
L’objectif n’est pas l’élégance académique. L’objectif est que deux équipes, chez deux clients, interprètent le même événement de la même façon.
Les champs qui comptent vraiment
Voici les champs qui méritent d’être explicitement modélisés, même si cela fâche un peu les amateurs de payloads “légers”.
Filing
Ce bloc décrit le document réglementaire lui-même.
filing.id
filing.jurisdiction
filing.regulator
filing.form_type, par exemple <span data-glossary-term="form4" data-autolink="glossary">Form 4</span>, MAR_PDMR
filing.accepted_at
filing.published_at
filing.amended, booléen
filing.original_filing_id, si correction
filing.source_url
La distinction accepted_at / published_at n’est pas décorative. Sur certains flux, l’heure d’acceptation et l’heure de disponibilité publique peuvent diverger. Si vous ne stockez qu’un seul timestamp, vous perdez la capacité de mesurer où la latence se forme réellement.
Issuer
Le titre concerné doit être identifié sans ambiguïté.
issuer.name
issuer.ticker
issuer.isin
issuer.cik pour les États-Unis, si pertinent
issuer.primary_exchange
issuer.country
Le ticker seul n’est pas un identifiant. C’est un surnom. Les surnoms fonctionnent très bien jusqu’au jour où ils cessent de fonctionner.
Insider
Le bloc initié est souvent sous-modélisé, alors qu’il détermine une large part de l’interprétation.
insider.name
insider.role
insider.relationship_type, dirigeant, administrateur, beneficial owner, personne liée
insider.is_pdmr
insider.is_close_associate
insider.ownership_nature, direct, indirect
insider.entity_name, si véhicule ou holding
Un achat du CEO n’est pas économiquement identique à un mouvement d’une structure familiale ou d’un trust, même si le formulaire les rapproche.
Transaction
C’est ici que beaucoup de systèmes simplifient trop.
transaction.code
transaction.side, buy, sell, acquire, dispose, exercise, gift, award, etc.
transaction.execution_date
transaction.settlement_date, si disponible
transaction.venue, on-market, off-market
transaction.nature_description
transaction.is_derivative
transaction.is_10b5_1, si applicable et disponible
transaction.plan_adoption_date, si disponible
Le champ side doit être une normalisation interne, pas une prétention universelle. Il faut conserver le code source du formulaire. Un A sur Form 4 n’est pas toujours un “achat” au sens où un gérant l’entend.
Economics
Le bloc économique doit distinguer ce qui est déclaré, ce qui est calculé, et ce qui est introuvable.
economics.quantity
economics.price
economics.currency
economics.notional_value
economics.post_transaction_holding
economics.ownership_percent, si disponible
economics.market_price_at_publish
economics.premium_discount_to_market
Si le prix n’est pas déclaré, il faut écrire n/a, pas 0. Le zéro a une signification économique. L’absence d’information aussi. Les confondre est une manière rapide de bâtir des dashboards absurdes.
Exemple de payload minimal, mais adulte
{
"event_id": "evt_01JXYZ",
"event_type": "insider_transaction.created",
"schema_version": "1.2.0",
"occurred_at": "2026-05-17T08:31:12Z",
"sent_at": "2026-05-17T08:31:14Z",
"delivery_attempt": 1,
"filing": {
"id": "fil_123",
"jurisdiction": "US",
"regulator": "SEC",
"form_type": "Form 4",
"accepted_at": "2026-05-17T08:30:41Z",
"published_at": "2026-05-17T08:30:55Z",
"amended": false,
"source_url": "https://www.sec.gov/Archives/..."
},
"issuer": {
"name": "Example Corp",
"ticker": "EXM",
"isin": "US0000000000",
"cik": "0000000000",
"primary_exchange": "NASDAQ",
"country": "US"
},
"insider": {
"name": "Jane Doe",
"role": "Chief Executive Officer",
"relationship_type": "officer",
"ownership_nature": "direct"
},
"transaction": {
"code": "P",
"side": "buy",
"execution_date": "2026-05-16",
"venue": "on_market",
"is_derivative": false,
"nature_description": "Open market purchase"
},
"economics": {
"quantity": 25000,
"price": 18.42,
"currency": "USD",
"notional_value": 460500,
"post_transaction_holding": 310000,
"market_price_at_publish": 18.55,
"premium_discount_to_market": -0.7
},
"compliance_flags": {
"amendment": false,
"possible_plan_trade": false,
"requires_manual_review": false
},
"links": {
"api_url": "https://api.vendor.com/filings/fil_123"
}
}
Ce payload n’est pas “petit”. C’est précisément pourquoi il est exploitable.
Filtrer le bruit, sinon le webhook devient un instrument de torture
Tous les filings ne se valent pas
Le premier ennemi d’une alerte utile est le volume non discriminé. Beaucoup de transactions d’initiés ne portent pas le même contenu informationnel. Il faut donc filtrer, ou au moins annoter.
Les catégories à traiter avec prudence :
- Attributions gratuites et vesting.
- Exercices d’options sans vente associée.
- Dons et transferts familiaux.
- Mouvements liés à des plans automatiques, notamment 10b5-1 aux États-Unis.
- Corrections et amendements.
- Transactions de très faible montant notionnel.
- Opérations sur dérivés dont l’exposition économique nette est difficile à lire.
Une alerte brute “insider transaction” est souvent trop vague. Une alerte utile ressemble davantage à : “CEO, achat marché, 460,5 kUSD, hors plan automatique signalé, décote de 0,7 % sur le prix de marché, première transaction en n/a jours”. Là, un gérant peut décider s’il ouvre le dossier ou s’il retourne à ses vrais problèmes.
Scoring, seuils, et agrégation
Le bon design consiste à séparer l’événement brut et le score d’intérêt. Le premier doit être fidèle à la source. Le second doit être configurable.
Quelques dimensions de scoring fréquentes :
- rôle de l’initié ;
- taille notionnelle ;
- répétition sur une fenêtre glissante ;
- proportion par rapport à la détention post-transaction ;
- proximité d’une publication de résultats ;
- type d’instrument ;
- présence d’un plan automatique ;
- achat versus vente ;
- transaction unique versus cluster multi-initiés.
L’agrégation est souvent plus informative que l’événement isolé. Trois achats de dirigeants sur dix jours n’ont pas le même sens qu’un seul achat symbolique. Le webhook peut donc porter soit un événement unitaire, soit un événement agrégé, soit les deux. À condition de le dire clairement dans event_type.