Aller au contenu
Sandbox

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.

Voir en Markdown

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 :

ChampContenu
entity_idL'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>.
nameLe nom de l'entité, tel que le graphe le connaît.
kindCe que l'entité est : brand ou organisation.
evidenceComment 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.
semanticsCe 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 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.

  • 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

    null est 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[].evidence sous la forme entite:<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é. match dit par quelle voie (jetons : un alias entier dans le libellé ; tronque : un fragment de libellé coupé par la banque). pattern est 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 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 (parent puis code). On s'arrête au parent quand la source s'y arrête : un rôle utility dit « réseau » sans dire lequel, et on rend alors utilities, jamais utilities.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_based sur 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. null quand 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. nature classe 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é. strength ne 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 nature participant ne peut jamais devenir une vérité du graphe partagé.

  • naturestring
    curateddeterministicproviderinferredparticipant
  • sourcestring
  • strengthnumber · 0–1
  • calibrationstring

    Toujours non_calibree dans 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_source ou role, et note, 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 sous logement.electricite. source dit d'où vient la ligne : entity_graph quand elle est portée par l'enseigne reconnue, generic_trade_entry quand elle est déduite d'un mot de métier lu dans le libellé. La première est bornée par confidence.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 (voir customization), source est absent : slug et label viennent 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.outcome peut rester resolved si l'archétype n'exigeait pas d'entité.

  • intermediariesarray<object>

    Les facilitateurs de paiement lus dans le libellé (PAYPAL *NETFLIX en donne un). Ils ne sont jamais la contrepartie. evidence est 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 à payment qui dit comment l'argent a circulé. evidence est 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 portent legacy_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 (voir signal_conflicts). no_rule : rien ne s'applique. Le suffixe +counterparty_nature dit 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 rail et transaction_type. Pas une donnée.

  • signal_conflictsarray<SignalConflict>

    Les signaux qui se contredisent. Quand il y en a, policy.outcome est partial : 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 : utilisez policy.outcome. 0 a un sens précis par champ : abstention (entity), rôle inconnu (counterparty), conflit sans ancêtre commun (transaction_type). location vaut toujours 0 : 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_calibree dans 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_calibree dans 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.

QuestionChampExemple
Qu'est-ce que c'est ? (type d'entité)counterparty.kindbrand
Que fait-elle ? (noms d'industrie, parent puis code)counterparty.semantics.activityretail.grocery, parent retail
Où l'argent est-il allé ? (lignes de budget)resolution.categoryalimentation.supermarche
Que s'est-il passé ?resolution.transaction_type.canonicalcard_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.

Note

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 (parent puis code). On s'arrête au parent quand la source s'y arrête : un rôle utility dit « réseau » sans dire lequel, et on rend alors utilities, jamais utilities.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_based sur 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. null quand 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. nature classe 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é. strength ne 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 nature participant ne peut jamais devenir une vérité du graphe partagé.

  • naturestring
    curateddeterministicproviderinferredparticipant
  • sourcestring
  • strengthnumber · 0–1
  • calibrationstring

    Toujours non_calibree dans 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_source ou role, et note, 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, avec counterparty_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.outcome peut rester resolved si l'archétype n'exigeait pas d'entité.
  • signal_conflicts non vide : deux signaux indépendants se contredisent, et policy.outcome passe à partial.
  • Le lieu : rien n'est résolu sur cet axe dans cette version, et confidence.location vaut toujours 0. L'IBAN de counterparty_hint est 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"
  }'
Shell

Extrait 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 }
}
JSON

Publié le 2026-09-17 11:19 UTC (version 1).

Cette page vous a-t-elle aidé ?