Contreparties et entités
Comment la résolution d'identité nomme une contrepartie, ce que le graphe d'entités distingue (marque, entité légale, intermédiaire) et ce qui reste volontairement non résolu.
Une transaction enrichie porte, sous resolution, ce que Noryo a compris de l'autre bout de l'opération : la contrepartie. Cette page décrit comment cette identité est établie, ce que le graphe sépare, et ce que signifie une absence.
Ce que rend la résolution d'identité
resolution.counterparty est un objet, ou null. Quand il est présent :
| Champ | Contenu |
|---|---|
entity_id | L'identifiant stable et opaque de l'entité dans le graphe partagé : un UUID nu, le même d'une réponse et d'un workspace à l'autre. series[].evidence le cite sous la forme entite:<uuid>. |
name | Le nom de l'entité, tel que le graphe le connaît. |
kind | Ce que l'entité est : brand ou organisation. |
evidence | Comment le motif a apparié le libellé : match (jetons : un alias entier lu dans le libellé ; tronque : un fragment coupé par la banque), pattern (l'alias apparié), coverage, et covered sur la voie tronquée. |
semantics | Ce que le graphe sait de l'entité (voir plus bas), ou null quand il n'en sait rien. |
coverage et covered sont des rapports de longueurs, des propriétés du texte et non une preuve d'identité : n'en faites pas un seuil (voir Sémantique des scores). À côté, counterparty_type qualifie la contrepartie en une chaîne (merchant, unknown dans les exemples du contrat).
Schéma Resolution
La forme rendue par le moteur `ti_v4`.
- policyobject
Ce que « RÉSOLU » veut dire dépend de la nature de la transaction. Un virement à une personne est
resolvedsans qu'aucune identité ne soit créée — c'est la bonne réponse, pas un échec. Un retrait d'espèces estresolvedsans marchand. Un achat carte, lui, exige sa contrepartie. - outcomestringrequis
resolved: toutes les dimensions exigées par l'archétype sont là.partial: la nature est connue, une dimension exigée manque — ou des signaux se contredisent, auquel cas on refuse de conclure.unresolved: on ignore jusqu'à la nature. Les erreurs techniques (401, 409, 503) ne sont jamais une issue sémantique : elles ne portent pas ce champ.resolvedpartialunresolved - archetypestringrequis
Le vocabulaire est français et c'est celui de la base (le vocabulaire des archétypes de résolution), conservé tel quel pour
ti_v1.inconnu: la nature même de la transaction est inconnue.non_couvert: la nature est connue mais aucune politique ne la couvre (missing = [resolution_policy]).achat_cartefrais_bancairesimpotindetermineprelevementremboursementretrait_especesrevenutransferttransfert_personneinconnunon_couvert - missingarray<string>requis
Les dimensions exigées par l'archétype et absentes.
- policy_versionstringrequis
ti_resolution_v1 - normalizedobject
Ce que le normaliseur a lu. Des chaînes, pas des scores.
- descriptorstring
- signalstring
- usefulstring
- residualstring
- normalizer_versionstring
- counterpartyobject· nullable
nullest un résultat, pas une panne : un inconnu honnête. - entity_idstring · uuid
L'identifiant stable de l'entité dans le graphe, sous forme d'UUID nu, sans préfixe. Il est opaque : ne lui prêtez aucune structure. Le même identifiant désigne la même entité d'une réponse à l'autre et d'un workspace à l'autre (le graphe est partagé ; l'identifiant n'est pas une donnée de votre workspace). Il est cité tel quel dans
series[].evidencesous la formeentite:<uuid>. - namestring
- kindstring
brandorganisation - evidenceobject
Comment le motif a apparié le libellé. Deux rapports de longueur, qui sont des propriétés du texte et pas une preuve d'identité.
matchdit par quelle voie (jetons: un alias entier dans le libellé ;tronque: un fragment de libellé coupé par la banque).patternest l'alias apparié, en clair. - matchstring
jetonstronque - patternstring
- coveragenumber ≥ 0
- coverednumber · 0.6–1
- semanticsCounterpartySemantics· nullable
Quatre choses différentes qui se ressemblent, et que ce bloc refuse de confondre. Le type d'entité (
counterparty.kind: marque, entité légale, intermédiaire de paiement) dit ce que c'est. L'activité (activity) dit ce que ça fait, en noms d'industrie. La catégorie (category, hors de cet objet) dit à quoi l'argent est allé, en lignes de budget. Le type de transaction (transaction_type) dit ce qui s'est passé. Aucun ne se déduit d'un autre. Et il n'existe aucuncategory = subscription: un abonnement n'est pas une sorte de dépense, c'est un modèle de relation commerciale.nullquand le graphe ne sait rien de cette entité — une abstention, pas une panne. - activityobject· nullable
Le métier, sur deux niveaux (
parentpuiscode). On s'arrête au parent quand la source s'y arrête : un rôleutilitydit « réseau » sans dire lequel, et on rend alorsutilities, jamaisutilities.electricity. Ce qui n'est pas su ne se complète pas. - codestring
- labelstring
- parentstring· nullable
- recurring_modelstring· nullable
Ce qui est habituel dans ce métier — pas un verdict sur cette transaction. Un service de streaming se vend par abonnement ; un fournisseur d'électricité facture de façon répétée sans qu'on s'abonne ; un supermarché vend à l'acte. C'est une plausibilité qui renforce un rythme déjà observé dans le workspace. Seul, il ne conclut jamais :
commonly_subscription_basedsur une transaction isolée ne fait pas un abonnement, et c'est la série (series[].type = subscription) qui tranche.commonly_subscription_basedcommonly_recurring_but_not_subscriptionusually_one_offboth_recurring_and_one_offunknownnull - rolesarray<string>
Les rôles portés par l'entité dans le graphe (
merchant,utility,government,financial_institution,payment_intermediary…). Un rôle n'est pas un métier, mais il en dit assez pour en dériver un quand aucun catalogue ne couvre l'entité. - legal_entityobject· nullable
Une marque n'est pas une entité légale. « Netflix » est ce qu'on lit sur le relevé ; « Netflix Inc » est ce qui contracte. Les deux existent séparément dans le graphe, reliés par
brand_of, parce que les fusionner ferait disparaître le jour où une marque change de propriétaire.nullquand aucune société mère n'est connue — pas quand il n'y en a pas. - entity_idstring · uuid
Le même espace d'identifiants que
counterparty.entity_id: UUID nu, opaque, stable. - namestring
- provenanceobject· nullable
D'où vient ce qu'on affirme.
natureclasse la connaissance par autorité déclarée, dans cet ordre :curated(une personne l'a vérifié),deterministic(dérivé mécaniquement d'un fait déjà tenu),provider(un tiers l'annonce),inferred(nous l'avons déduit),participant(un seul client l'a dit). Cet ordre est déclaré, pas déduit d'un nombre : sans lui, un 0,95 déduit l'emporterait sur un 0,90 vérifié.strengthne départage qu'à nature égale, et n'est pas calibrée. Et aucune connaissance globale ne vient d'un seul client : ce qu'un workspace observe reste dans ce workspace. Une natureparticipantne peut jamais devenir une vérité du graphe partagé. - naturestring
curateddeterministicproviderinferredparticipant - sourcestring
- strengthnumber · 0–1
- calibrationstring
Toujours
non_calibreedans cette version, et c'est une contrainte, pas une convention : la valeur est un vocabulaire en base, les colonnes qui la portent y font référence, et une garde refuse tout littéral hors vocabulaire chez chaque producteur. Le jour où une calibration réelle existe, elle entrera par une migration déclarée, avec le corpus qui la défend.non_calibree - evidenceobject
Comment la provenance a été établie. Les clefs varient :
derivation(categorie_de_depense_vers_activite,role_vers_activite…),categorie_sourceourole, etnote, une phrase constante en français. Aucune de ces valeurs n'est un nombre. - counterparty_typestring
- counterparty_notestring· nullable
Dit pourquoi aucune identité n'a été établie.
- categoryobject· nullable
Une catégorie n'est pas une identité. Quand le libellé désigne un métier (« BOULANGERIE DUPONT », « PHARMACIE DE LA GARE ») et non une enseigne connue, la réponse rend ce métier ici et laisse
counterpartyànull. Rendre « Boulangerie » comme contrepartie reviendrait à nommer un rayon à la place d'une entreprise. Et c'est une ligne de budget, pas un métier. Cette catégorie répond à « à quoi cet argent est-il allé », du point de vue de la personne. Ce que l'entité fait est un autre champ,counterparty.semantics.activity, et les deux ne se substituent pas : EDF vend de l'électricité (activity = utilities.electricity) et la dépense se range souslogement.electricite.sourcedit d'où vient la ligne :entity_graphquand elle est portée par l'enseigne reconnue,generic_trade_entryquand elle est déduite d'un mot de métier lu dans le libellé. La première est bornée parconfidence.entity— une enseigne mal reconnue ne donne pas une catégorie sûre. Quand une règle de votre organisation a posé la catégorie (voircustomization),sourceest absent :slugetlabelviennent alors du catalogue Noryo, et aucune des deux origines Noryo ne serait vraie. - slugstring
- labelstring· nullable
- sourcestring
entity_graphgeneric_trade_entry - identity_abstentionstring· nullable
Pourquoi le moteur a refusé de nommer, alors qu'il aurait pu.
trade_not_identity: un métier a été reconnu, pas une enseigne.atm_operator_not_counterparty: sur un mouvement d'espèces, la banque reconnue exploite le distributeur — elle n'est pas en face.account_bank_not_counterparty: sur un frais bancaire, c'est la banque du compte, et la nommer n'apprend rien.person_named_not_brand: le libellé nomme une personne, et l'enseigne reconnue appartient au motif du virement. Une abstention n'est pas une panne :policy.outcomepeut resterresolvedsi l'archétype n'exigeait pas d'entité. - intermediariesarray<object>
Les facilitateurs de paiement lus dans le libellé (
PAYPAL *NETFLIXen donne un). Ils ne sont jamais la contrepartie.evidenceest un code et une source — plus jamais le motif d'appariement lui-même, qui est une règle interne. - namestringrequis
- rolestringrequis
- entity_idstring · uuid· nullable
L'entité du facilitateur dans le graphe, quand elle y est.
- carries_sub_merchantboolean
- evidenceobjectrequis
- codestringrequis
Le code du facilitateur au référentiel.
- sourcestringrequis
referentiel_facilitateurs - transaction_typeobject
Ce que la transaction signifie, par opposition à
paymentqui dit comment l'argent a circulé.evidenceest un code de règle, pas une explication : la note interne de la règle sortait ici dans une version antérieure ; les réponses créées alors portentlegacy_note_redacted. - canonicalstringrequis
- evidencestringrequis
rail_rule: le rail seul a décidé.descriptor_rule: le libellé seul.descriptor_sense_rail_mechanism: le libellé donne le sens, le rail le mécanisme, sans conflit.rail_and_descriptor_agree: les deux disent la même chose.descriptor_refines_rail/rail_refines_descriptor: l'un précise l'autre.rail_descriptor_conflict: contradiction, aucune certitude fabriquée (voirsignal_conflicts).no_rule: rien ne s'applique. Le suffixe+counterparty_naturedit que la nature de la contrepartie a affiné le type.^(rail_rule|descriptor_rule|descriptor_sense_rail_mechanism|rail_and_descriptor_agree|descriptor_refines_rail|rail_refines_descriptor|rail_descriptor_conflict|no_rule)(\+counterparty_nature)?$|^legacy_note_redacted$ - contradictionstring· nullablerequis
- paymentobject· nullable
Ce que le moteur a compris du rail et du mécanisme de paiement.
- railstring· nullable
- mechanismstring· nullable
- notestring· nullable
Une phrase explicative constante, en français, qui rappelle la différence entre
railettransaction_type. Pas une donnée. - signal_conflictsarray<SignalConflict>
Les signaux qui se contredisent. Quand il y en a,
policy.outcomeestpartial: on refuse de conclure. - dimensionstringrequis
- signalsarray<string>requis
- resolutionstringrequis
Une phrase, en français : comment le conflit a été arbitré.
- resolved_tostringrequis
- submerchant_lanestring
L'issue de la voie « sous-marchand » (un facilitateur porte l'enseigne réelle).
none: voie non ouverte.no_candidate: ouverte, aucune entité.resolved: une entité unique.ambiguous: plusieurs, abstention. Absent sur les réponses les plus anciennes, créées avant que cette voie existe.noneno_candidateresolvedambiguous - truncated_lanestring
L'issue de la voie « libellé tronqué » (la banque a coupé le nom). Mêmes valeurs que
submerchant_lane. Absent sur les réponses les plus anciennes, créées avant que cette voie existe.noneno_candidateresolvedambiguous - confidenceobject
Le nom est conservé pour
ti_v1; ce n'est pas une confiance. Chacun de ces nombres est une constante déclarée — posée par la personne qui a écrit le motif ou la règle, et lue telle quelle. Toute transaction qui touche le même motif reçoit le même nombre. Mesuré sur 644 libellés : la précision en fonction du seuil n'est pas monotone — 0,85 donne 0,86 de précision, 0,88 donne 0,33, 0,92 donne 0,25, 0,97 donne 0,79. Ce nombre n'ordonne pas le juste avant le faux. Ne l'utilisez ni comme probabilité ni comme seuil : utilisezpolicy.outcome.0a un sens précis par champ : abstention (entity), rôle inconnu (counterparty), conflit sans ancêtre commun (transaction_type).locationvaut toujours0: rien n'est résolu sur cet axe dans cette version. - entitynumber · 0–1requis
- counterpartynumber · 0–1requis
- transaction_typenumber · 0–1requis
- categorynumber · 0–1requis
- locationnumberrequis
0 - calibrationstringrequis
Toujours
non_calibreedans cette version, et c'est une contrainte, pas une convention : la valeur est un vocabulaire en base, les colonnes qui la portent y font référence, et une garde refuse tout littéral hors vocabulaire chez chaque producteur. Le jour où une calibration réelle existe, elle entrera par une migration déclarée, avec le corpus qui la défend.non_calibree - timings_msobject
Des durées, en millisecondes. Rien à voir avec une confiance.
- normalizationnumber
- entity_resolutionnumber
- submerchantnumber
- totalnumber
- versionsobject
Les versions qui ont produit cette réponse. Un client qui conserve un nombre doit conserver la version à côté : la même valeur, sous une autre version, peut ne plus mesurer la même chose.
- graphstring
L'ontologie du graphe d'entités (
onto_v1). - rulesstring
Les règles de type de transaction (
txtype_v1). - enginestringrequis
Le moteur de résolution (
ti_v4). - resolution_policystringrequis
La même valeur que
policy.policy_version. - calibrationstringrequis
Toujours
non_calibreedans cette version, et c'est une contrainte, pas une convention : la valeur est un vocabulaire en base, les colonnes qui la portent y font référence, et une garde refuse tout littéral hors vocabulaire chez chaque producteur. Le jour où une calibration réelle existe, elle entrera par une migration déclarée, avec le corpus qui la défend.non_calibree
Le graphe d'entités : marque, entité légale, intermédiaire
Le graphe sépare trois choses qu'un relevé bancaire mélange.
La marque est ce que vous lisez sur le relevé : « Netflix », « Monoprix ». La réponse la rend en contrepartie, avec kind = brand.
L'entité légale est ce qui contracte : « Netflix Inc ». Elle vit séparément dans le graphe, reliée à la marque par brand_of, et se lit dans counterparty.semantics.legal_entity (entity_id, name). Les fusionner ferait disparaître le jour où une marque change de propriétaire. legal_entity vaut null quand aucune société mère n'est connue, pas quand il n'y en a pas.
L'intermédiaire de paiement est le facilitateur lu dans le libellé : PAYPAL *NETFLIX en donne un. Il n'est jamais la contrepartie. Il se lit dans resolution.intermediaries[] : name, role, entity_id quand il est dans le graphe, carries_sub_merchant, et une evidence (code et source). submerchant_lane dit l'issue de la voie « sous-marchand », ouverte quand un facilitateur porte l'enseigne réelle : none (non ouverte), no_candidate, resolved (une entité unique) ou ambiguous (plusieurs candidats, abstention). truncated_lane fait de même pour un libellé coupé par la banque.
Quatre choses qui se ressemblent
Quatre champs répondent à quatre questions, et aucun ne se déduit d'un autre.
| Question | Champ | Exemple |
|---|---|---|
| Qu'est-ce que c'est ? (type d'entité) | counterparty.kind | brand |
Que fait-elle ? (noms d'industrie, parent puis code) | counterparty.semantics.activity | retail.grocery, parent retail |
| Où l'argent est-il allé ? (lignes de budget) | resolution.category | alimentation.supermarche |
| Que s'est-il passé ? | resolution.transaction_type.canonical | card_purchase |
EDF illustre l'écart entre activité et catégorie : l'entité vend de l'électricité (activity = utilities.electricity) et la dépense se range sous logement.electricite. L'activité s'arrête au parent quand la source s'y arrête : un rôle utility donne utilities, jamais utilities.electricity. Le type de transaction, lui, est détaillé dans Types de transaction.
Il n'existe aucune category = subscription. Un abonnement n'est pas une sorte de dépense, c'est un modèle de relation commerciale : il se lit dans recurring_model et, surtout, dans les séries.
Une catégorie n'est pas non plus une identité. Quand le libellé désigne un métier (« BOULANGERIE DUPONT ») et non une enseigne connue, la réponse rend ce métier dans category avec source = generic_trade_entry et laisse counterparty à null : « Boulangerie » nommerait un rayon, pas une entreprise. source = entity_graph signale au contraire une catégorie portée par l'enseigne reconnue.
recurring_model : un modèle de relation, pas une catégorie
counterparty.semantics.recurring_model dit ce qui est habituel dans ce métier : commonly_subscription_based (le streaming se vend par abonnement), commonly_recurring_but_not_subscription (un fournisseur d'électricité facture de façon répétée sans qu'on s'abonne), usually_one_off (un supermarché vend à l'acte), both_recurring_and_one_off, unknown, ou null.
Ce n'est pas un verdict sur la transaction envoyée, mais une plausibilité qui renforce un rythme déjà observé dans votre workspace ; seule, elle ne conclut jamais. commonly_subscription_based sur une transaction isolée ne fait pas un abonnement : c'est la série qui tranche, par series[].type = subscription. Et une contrepartie n'est pas une série : une même enseigne peut porter plusieurs séries, et une série ne se réduit jamais à « toutes les transactions de cette contrepartie » (voir Séries récurrentes).
Provenance : d'où vient ce qu'on affirme
counterparty.semantics.provenance dit d'où vient la connaissance. nature la classe par autorité déclarée, dans cet ordre : curated (une personne l'a vérifié), deterministic (dérivé mécaniquement d'un fait déjà tenu), provider (un tiers l'annonce), inferred (Noryo l'a déduit), participant (un seul client l'a dit). Cet ordre est déclaré, jamais déduit d'un nombre : strength (classe authority_tiebreak) ne départage que deux sources de même nature, et n'est pas calibrée (calibration = non_calibree).
Ce qu'un workspace observe reste dans ce workspace : une nature participant ne devient jamais une vérité du graphe partagé.
roles liste les rôles portés par l'entité dans le graphe (notamment merchant, utility, government, financial_institution, payment_intermediary) ; un rôle n'est pas un métier, mais il permet d'en dériver un quand aucun catalogue ne couvre l'entité.
Schéma CounterpartySemantics
Quatre choses différentes qui se ressemblent, et que ce bloc refuse de confondre. Le type d'entité (`counterparty.kind` : marque, entité légale, intermédiaire de paiement) dit ce que c'est. L'activité (`activity`) dit ce que ça fait, en noms d'industrie. La catégorie (`category`, hors de cet objet) dit à quoi l'argent est allé, en lignes de budget. Le type de transaction (`transaction_type`) dit ce qui s'est passé. Aucun ne se déduit d'un autre. Et il n'existe aucun `category = subscription` : un abonnement n'est pas une sorte de dépense, c'est un modèle de relation commerciale. `null` quand le graphe ne sait rien de cette entité — une abstention, pas une panne.
- activityobject· nullable
Le métier, sur deux niveaux (
parentpuiscode). On s'arrête au parent quand la source s'y arrête : un rôleutilitydit « réseau » sans dire lequel, et on rend alorsutilities, jamaisutilities.electricity. Ce qui n'est pas su ne se complète pas. - codestring
- labelstring
- parentstring· nullable
- recurring_modelstring· nullable
Ce qui est habituel dans ce métier — pas un verdict sur cette transaction. Un service de streaming se vend par abonnement ; un fournisseur d'électricité facture de façon répétée sans qu'on s'abonne ; un supermarché vend à l'acte. C'est une plausibilité qui renforce un rythme déjà observé dans le workspace. Seul, il ne conclut jamais :
commonly_subscription_basedsur une transaction isolée ne fait pas un abonnement, et c'est la série (series[].type = subscription) qui tranche.commonly_subscription_basedcommonly_recurring_but_not_subscriptionusually_one_offboth_recurring_and_one_offunknownnull - rolesarray<string>
Les rôles portés par l'entité dans le graphe (
merchant,utility,government,financial_institution,payment_intermediary…). Un rôle n'est pas un métier, mais il en dit assez pour en dériver un quand aucun catalogue ne couvre l'entité. - legal_entityobject· nullable
Une marque n'est pas une entité légale. « Netflix » est ce qu'on lit sur le relevé ; « Netflix Inc » est ce qui contracte. Les deux existent séparément dans le graphe, reliés par
brand_of, parce que les fusionner ferait disparaître le jour où une marque change de propriétaire.nullquand aucune société mère n'est connue — pas quand il n'y en a pas. - entity_idstring · uuid
Le même espace d'identifiants que
counterparty.entity_id: UUID nu, opaque, stable. - namestring
- provenanceobject· nullable
D'où vient ce qu'on affirme.
natureclasse la connaissance par autorité déclarée, dans cet ordre :curated(une personne l'a vérifié),deterministic(dérivé mécaniquement d'un fait déjà tenu),provider(un tiers l'annonce),inferred(nous l'avons déduit),participant(un seul client l'a dit). Cet ordre est déclaré, pas déduit d'un nombre : sans lui, un 0,95 déduit l'emporterait sur un 0,90 vérifié.strengthne départage qu'à nature égale, et n'est pas calibrée. Et aucune connaissance globale ne vient d'un seul client : ce qu'un workspace observe reste dans ce workspace. Une natureparticipantne peut jamais devenir une vérité du graphe partagé. - naturestring
curateddeterministicproviderinferredparticipant - sourcestring
- strengthnumber · 0–1
- calibrationstring
Toujours
non_calibreedans cette version, et c'est une contrainte, pas une convention : la valeur est un vocabulaire en base, les colonnes qui la portent y font référence, et une garde refuse tout littéral hors vocabulaire chez chaque producteur. Le jour où une calibration réelle existe, elle entrera par une migration déclarée, avec le corpus qui la défend.non_calibree - evidenceobject
Comment la provenance a été établie. Les clefs varient :
derivation(categorie_de_depense_vers_activite,role_vers_activite…),categorie_sourceourole, etnote, une phrase constante en français. Aucune de ces valeurs n'est un nombre.
policy.outcome : ce que « résolu » veut dire
resolution.policy rend l'issue de la résolution :
outcome:resolved(toutes les dimensions exigées par l'archétype sont là),partial(la nature est connue, mais une dimension exigée manque ou des signaux se contredisent),unresolved(la nature même de la transaction est inconnue).archetype: la nature de la transaction, dans le vocabulaire français de la base :achat_carte,prelevement,transfert_personne,retrait_especes,frais_bancaires,impot,remboursement,revenu,transfert,indetermine,inconnu,non_couvert.missing: les dimensions exigées et absentes (counterparty_entity,counterparty_type,transaction_type,resolution_policy).
Ce que « résolu » veut dire dépend de l'archétype. Un virement à une personne est resolved sans qu'aucune identité ne soit créée : c'est la bonne réponse, pas un échec. Un retrait d'espèces est resolved sans marchand. Un achat carte, lui, exige sa contrepartie : sans elle, outcome vaut partial et missing contient counterparty_entity.
Pour décider d'un traitement, lisez policy.outcome, jamais les nombres de confidence : ce sont des constantes déclarées par motif, pas des probabilités.
Ce qui reste non résolu, et pourquoi
Une absence est un résultat, et la réponse dit lequel.
counterparty=null, aveccounterparty_note: aucune identité n'a été établie, et la note dit pourquoi.identity_abstention: le moteur a refusé de nommer alors qu'il l'aurait pu :trade_not_identity(un métier reconnu, pas une enseigne),atm_operator_not_counterparty(la banque reconnue exploite le distributeur),account_bank_not_counterparty(sur un frais bancaire, nommer la banque du compte n'apprend rien),person_named_not_brand(le libellé nomme une personne).policy.outcomepeut resterresolvedsi l'archétype n'exigeait pas d'entité.signal_conflictsnon vide : deux signaux indépendants se contredisent, etpolicy.outcomepasse àpartial.- Le lieu : rien n'est résolu sur cet axe dans cette version, et
confidence.locationvaut toujours0. L'IBAN decounterparty_hintest réduit dès l'entrée à son pays et à son code banque.
Lisez signals.used et signals.ignored : c'est la seule façon de savoir si un signal envoyé pèse sur la réponse.
Exemple
L'exemple achat_carte du contrat :
curl -X POST https://api.noryo.app/transactions/v1/enrichments \
-H "Authorization: Bearer $NORYO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"descriptor": "CARTE 09/09 MONOPRIX PARIS 15",
"direction": "outgoing",
"occurred_at": "2026-09-09T07:31:00+02:00",
"amount": { "value": "49.90", "currency": "EUR" },
"payment": { "rail": "card", "mcc": "5411", "card_present": true },
"location_hint": { "country": "FR" },
"account_hint": { "iban": "FR7630006000011234567890189" },
"external_transaction_id": "tx-2026-09-09-0042"
}'ShellExtrait de la resolution rendue :
{
"policy": { "outcome": "resolved", "archetype": "achat_carte", "missing": [], "policy_version": "ti_resolution_v1" },
"counterparty": {
"entity_id": "b83d1756-258c-4541-adc7-54eec83dbd3c",
"name": "Monoprix",
"kind": "brand",
"evidence": { "match": "jetons", "pattern": "MONOPRIX", "coverage": 0.4 },
"semantics": {
"roles": ["merchant"],
"activity": { "code": "retail.grocery", "label": "alimentation generale", "parent": "retail" },
"legal_entity": { "entity_id": "5ecee4f8-fab0-444f-8711-29ff6e3f875a", "name": "Groupe Casino" },
"recurring_model": "usually_one_off",
"provenance": { "nature": "curated", "source": "catalogue_cure", "strength": 0.75, "calibration": "non_calibree" }
}
},
"counterparty_type": "merchant",
"counterparty_note": null,
"category": { "slug": "alimentation.supermarche", "label": "Supermarché", "source": "entity_graph" },
"identity_abstention": null,
"intermediaries": [],
"transaction_type": { "canonical": "card_purchase", "evidence": "rail_rule", "contradiction": null }
}JSONPublié le 2026-09-17 11:19 UTC (version 1).