> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Confirmation de propriété du portefeuille : Travel Rule

> Confirmez ou refusez avec Didit que votre client contrôle le portefeuille bénéficiaire d'un transfert Travel Rule entrant en UNCONFIRMED_OWNERSHIP.



Prompt API de confirmation de la propriété du portefeuille
        Copier le prompt dans le presse-papiers



      
      

\<pre>

\`Confirm or deny wallet ownership on a Travel Rule transfer waiting on the beneficiary side - typically the beneficiary leg of an INTERNAL-rail transfer whose wallet address book entry has not been ownership-verified yet, a transfer whose counterparty wallet was declared self-hosted (counterparty.payment_method.method_type: "unhosted_wallet"), an inbound transfer in ON_HOLD, or an inbound TRP inquiry a compliance officer resolves by hand.

Endpoint:
POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ownership/

Authentication:
Use the x-api-key header with my Didit API key. {transaction_id} is the Didit transaction uuid of the transfer your own application holds: on an INTERNAL-rail transfer that is your (beneficiary) side; on a declared self-hosted wallet it is the transaction you created, outbound or inbound.

Request body:
\{"confirmed": true}   or   {"confirmed": false}
Optionally {"confirmed": true, "wallet_address": "0x..."} - the payment address to return to the counterparty on an inbound TRP transfer.
On a declared self-hosted wallet transfer with no counterparty wallet on it, "wallet_address" supplies the wallet to verify; if neither the transfer nor the request names one, the request is rejected with 400.

Accepted states (anything else -> 409 "Transfer is not awaiting ownership confirmation."):
\- UNCONFIRMED_OWNERSHIP, in either direction.
\- ON_HOLD on an inbound transfer.
\- UNCONFIRMED_OWNERSHIP, ON_HOLD or COUNTERPARTY_MISMATCHED_DATA on an inbound TRP transfer.

Behavior on a transfer Didit created itself (INTERNAL rail, sunrise registration, declared self-hosted wallet):
\- confirmed: true - marks the matching wallet address book entry ownership-verified, then runs the beneficiary name match on both sides: COMPLETED on a pass, COUNTERPARTY_MISMATCHED_DATA on a fail.
An inbound transfer whose deposit already settled then moves on to FINISHED.
\- confirmed: true on a declared self-hosted wallet - records that the customer verified who controls the counterparty wallet and completes the transfer (COMPLETED), outbound or inbound; an inbound deposit whose on-chain hash is already known moves on to FINISHED. The wallet is the counterparty's: the destination of a withdrawal, the originator's source wallet of a deposit. If it is not in the wallet address book yet, it is added as ownership-verified under the counterparty's name; if the book already holds it under a different holder name, the transfer goes to COUNTERPARTY_MISMATCHED_DATA.
\- confirmed: false - moves both sides of the transfer to COUNTERPARTY_VASP_GENERAL_DECLINE.
\- Resolving an inbound ON_HOLD with no matching entry, or confirming a declared self-hosted wallet, creates the entry from the transfer's wallet address and marks it verified.

Behavior on an inbound TRP transfer (answering the counterparty's inquiry):
\- confirmed: true - needs a payment address, taken from the request's wallet_address, then the matched entry, then beneficiary_data.wallet_address.
Didit creates or verifies the entry, posts the inquiry-resolution callback to the counterparty, sets ownership_confirmed and moves the transfer to COMPLETED.
\- confirmed: false - posts a declined resolution and moves the transfer to COUNTERPARTY_VASP_GENERAL_DECLINE.

Transfers a network delivered (GTR or Sygna Bridge):
\- An inbound transfer that waits for your review (UNCONFIRMED_OWNERSHIP, ON_HOLD or COUNTERPARTY_MISMATCHED_DATA) is decided here: confirmed: true approves it (send wallet_address when the transfer names none), confirmed: false declines it. Didit answers the network after the response, with retries; the response's delivery field shows that answer.
\- VerifyVASP takes its answer when it asks, so a VerifyVASP transfer that would need your review is declined at once and cannot be decided here.
\- Receiving over a network is switched on by Didit per network, and none is switched on today.

What to read from the response:
\- The full transfer object. originator_data/beneficiary_data stay masked on inbound transfers (data_masked: true) until ownership is confirmed; data_unmasked then records when, why and by whom. data_match and mismatched_fields name the fields that differ after a mismatch.

Alternative: instead of this API call, send the end customer through the hosted wallet-ownership widget (POST /v3/travel-rule/widget-session/) and let them prove control cryptographically.

Failure modes:
\- 400 - on an inbound TRP approval with no payment address available: {"wallet_address": ["wallet_address is required to approve."]}.
\- 409 - the transfer is not in one of the accepted states, no entry in your wallet address book matches the transfer's wallet address (an inbound TRP approval, and an inbound ON_HOLD transfer that carries beneficiary_data.wallet_address, and a declared self-hosted wallet, create the missing entry instead), an INTERNAL transfer from another Didit customer needs a control proof (signed message or test deposit) first, or a network transfer was already answered over its network (a VerifyVASP transfer, or a GTR or Sygna Bridge transfer already decided).
\- 502 - the counterparty's TRP inquiry-resolution callback could not be delivered; the transfer keeps its current status.
\- 404 - unknown transaction or no Travel Rule transfer attached.

Full guide: /transaction-monitoring/travel-rule#confirming-wallet-ownership.`

\</pre>



      
      

Coller dans

## Portefeuilles auto-hébergésLorsque le portefeuille de la contrepartie a été déclaré auto-hébergé (`counterparty.payment_method.method_type: "unhosted_wallet"`), le transfert reste en attente à l'état `UNCONFIRMED_OWNERSHIP`.
Appeler cet endpoint avec `confirmed: true` enregistre que votre client a vérifié qui contrôle ce portefeuille et finalise le transfert (`COMPLETED`), que ce soit pour les retraits sortants ou les dépôts entrants.
Un dépôt entrant dont le hash on-chain est déjà connu passe à `FINISHED`.Le portefeuille vérifié est celui de la contrepartie : la destination d'un retrait sortant, ou la source (le portefeuille du donneur d'ordre) d'un dépôt entrant.
Didit l'ajoute au carnet d'adresses des portefeuilles comme portefeuille dont la propriété est vérifiée, au nom de la contrepartie. Il est donc comparé au nom de la contrepartie (le donneur d'ordre, pour un dépôt).
Si le carnet d'adresses contient déjà ce portefeuille sous un autre nom de titulaire, le transfert passe à `COUNTERPARTY_MISMATCHED_DATA`.Si le transfert ne mentionne aucun portefeuille de contrepartie, transmettez `wallet_address` dans le corps de la requête.
Lorsque ni le transfert ni la requête ne fournissent d'adresse, la requête est rejetée avec `400`.`confirmed: false` refuse le transfert (`COUNTERPARTY_VASP_GENERAL_DECLINE`).


## OpenAPI

````yaml fr/openapi-25.json POST /v3/transactions/{transaction_id}/travel-rule/ownership/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de vérification d'identité. Authentifiez-vous avec l'en-tête x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/transactions/{transaction_id}/travel-rule/ownership/:
    post:
      tags:
        - Travel Rule
      summary: Confirmer ou refuser la propriété du portefeuille
      description: >-
        Résolvez un transfert en attente de propriété du portefeuille :
        appelez-le de votre côté du transfert lorsqu'il est à l'état
        UNCONFIRMED_OWNERSHIP, ou lorsqu'il s'agit d'un transfert entrant à
        l'état ON_HOLD. La confirmation marque l'entrée correspondante du carnet
        d'adresses de portefeuilles comme vérifiée quant à sa propriété (pour un
        transfert entrant ON_HOLD sans entrée, Didit en crée une à partir de
        beneficiary_data.wallet_address) et exécute la correspondance du nom du
        bénéficiaire des deux côtés du transfert ; le refus rejette les deux
        côtés. Un transfert entrant dont le dépôt est déjà réglé passe à
        FINISHED lorsque la correspondance réussit. Lorsque le portefeuille de
        la contrepartie a été déclaré auto-hébergé
        (counterparty.payment_method.method_type: unhosted_wallet), la
        confirmation enregistre que le client a vérifié qui contrôle ce
        portefeuille et finalise le transfert (COMPLETED) dans les deux sens, ou
        FINISHED pour un dépôt entrant dont le hash on-chain est déjà connu. Le
        portefeuille vérifié est celui de la contrepartie : la destination d'un
        retrait sortant, ou la source (le portefeuille du donneur d'ordre) d'un
        dépôt entrant. S'il ne figure pas encore dans votre carnet d'adresses de
        portefeuilles, Didit l'ajoute comme vérifié quant à sa propriété sous le
        nom de la contrepartie ; si le carnet le contient déjà sous un nom de
        titulaire différent, le transfert passe à COUNTERPARTY_MISMATCHED_DATA.
        Pour un transfert TRP entrant à l'état UNCONFIRMED_OWNERSHIP, ON_HOLD ou
        COUNTERPARTY_MISMATCHED_DATA, Didit transmet plutôt votre décision au
        VASP d'origine : l'approbation renvoie l'adresse de paiement
        (wallet_address ou l'adresse de l'entrée correspondante) et fait passer
        le transfert à COMPLETED, tandis que le refus le rejette. Le même appel
        tranche également un transfert entrant envoyé par une contrepartie GTR
        ou Sygna Bridge et qui attend votre examen (`UNCONFIRMED_OWNERSHIP`,
        `ON_HOLD` ou `COUNTERPARTY_MISMATCHED_DATA`) : `confirmed: true`
        l'approuve (transmettez `wallet_address` lorsque le transfert n'en
        indique aucune) et `confirmed: false` le refuse, et le réseau reçoit la
        réponse après celle-ci, avec des réessais. VerifyVASP reçoit sa réponse
        au moment où il formule la demande ; ainsi, un transfert VerifyVASP qui
        nécessiterait votre examen est refusé immédiatement et ne peut pas être
        tranché ultérieurement.
      operationId: confirmTravelRuleOwnership
      parameters:
        - name: transaction_id
          in: path
          required: true
          description: >-
            UUID stable attribué par Didit à la transaction que votre
            application détient pour ce transfert : la transaction côté
            bénéficiaire sur un transfert via le réseau INTERNAL, ou la
            transaction que vous avez créée (entrante ou sortante) lorsque le
            portefeuille de la contrepartie a été déclaré auto-hébergé.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TravelRuleOwnershipConfirmRequest'
            example:
              confirmed: true
      responses:
        '200':
          description: >-
            Le transfert mis à jour. Pour un transfert entrant, les
            originator_data/beneficiary_data de la contrepartie restent masqués
            (`data_masked: true`) jusqu'à ce que l'actionnariat soit confirmé,
            puis `data_unmasked` enregistre quand, pourquoi et par qui.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelRuleTransferDetail'
        '400':
          description: "Erreur de validation\_: confirmed est manquant, une approbation TRP entrante n'a pas de wallet_address ni d'adresse de repli, ou `confirmed: true` sur un transfert déclaré vers un portefeuille auto-hébergé qui ne nomme aucun portefeuille de contrepartie alors qu'aucune `wallet_address` n'a été envoyée."
          content:
            application/json:
              examples:
                No payment address:
                  value:
                    wallet_address:
                      - wallet_address is required to approve.
        '404':
          description: >-
            Transaction inconnue, ou la transaction n'a aucun transfert Travel
            Rule.
        '409':
          description: >-
            Le transfert n'est pas en attente de confirmation de propriété,
            aucune entrée du carnet d'adresses de portefeuille ne correspond à
            son portefeuille de contrepartie, un transfert INTERNAL provenant
            d'un autre client Didit nécessite une preuve de contrôle (un message
            signé ou un dépôt test) avant de pouvoir être confirmé, ou une
            réponse a déjà été apportée au transfert de réseau via son réseau
            (un transfert VerifyVASP, ou un transfert GTR ou Sygna Bridge pour
            lequel vous ou Didit avez déjà pris une décision).
          content:
            application/json:
              examples:
                Not awaiting confirmation:
                  value:
                    detail: Transfer is not awaiting ownership confirmation.
                No matching address book entry:
                  value:
                    detail: wallet address entry no longer available
        '502':
          description: >-
            Transfert TRP entrant uniquement : Didit n'a pas pu transmettre
            votre décision au VASP d'origine, le statut du transfert ne change
            donc pas.
          content:
            application/json:
              examples:
                Callback not delivered:
                  value:
                    detail: >-
                      Counterparty inquiry-resolution callback could not be
                      delivered.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            curl -X POST
            https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ownership/
            \
              -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \
              -d '{"confirmed": true}'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.transactions.travel_rule.confirm_ownership(
                "11111111-2222-3333-4444-555555555555",
                confirmed=True,
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: >-
            import Didit from "@didit-protocol/sdk-node";


            // Reads DIDIT_API_KEY.

            const didit = new Didit();


            const result = await
            didit.transactions.travelRule.confirmOwnership("11111111-2222-3333-4444-555555555555",
            {
              confirmed: true,
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ConfirmOwnership(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleOwnershipConfirmRequest{\n\tConfirmed: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import me.didit.Didit;

            import me.didit.types.TravelRuleOwnershipConfirmRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.transactions().travelRule().confirmOwnership("11111111-2222-3333-4444-555555555555",
            TravelRuleOwnershipConfirmRequest.builder()
                    .confirmed(true)
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: >-
            <?php


            require 'vendor/autoload.php';


            use Didit\DiditClient;


            // Reads DIDIT_API_KEY.

            $didit = new DiditClient();


            $result =
            $didit->transactions->travelRule->confirmOwnership('11111111-2222-3333-4444-555555555555',
            [
                'confirmed' => true,
            ]);

            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.transactions.travel_rule.confirm_ownership(
              "11111111-2222-3333-4444-555555555555",
              confirmed: true
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await
            client.Transactions.TravelRule.ConfirmOwnershipAsync("11111111-2222-3333-4444-555555555555",
            new TravelRuleOwnershipConfirmRequest

            {
                Confirmed = true,
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    TravelRuleOwnershipConfirmRequest:
      type: object
      required:
        - confirmed
      properties:
        confirmed:
          type: boolean
          description: true pour confirmer la propriété, false pour la refuser.
        wallet_address:
          type: string
          default: ''
          description: "Transferts TRP entrants\_: l'adresse de paiement que Didit renvoie au VASP d'origine lorsque vous approuvez. Correspond par défaut à l'adresse de l'entrée correspondante du carnet d'adresses, puis à beneficiary_data.wallet_address. Sur un transfert vers un portefeuille auto-hébergé déclaré qui ne nomme aucun portefeuille de contrepartie, le portefeuille dont vous avez vérifié la propriété\_; sans cela, la requête est rejetée avec une erreur 400. Ignoré pour les autres transferts."
    TravelRuleTransferDetail:
      type: object
      description: >-
        Objet de transfert complet renvoyé par les endpoints de confirmation
        d'actionnariat et de finalisation/annulation. Tant que l'actionnariat du
        portefeuille d'un transfert entrant n'est pas confirmé, les champs
        `originator_data` et `beneficiary_data` de la contrepartie sont renvoyés
        masqués (la première lettre de chaque mot est conservée ; le
        portefeuille, la blockchain et le routage VASP restent lisibles) et
        `data_masked` est à true.
      properties:
        uuid:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - AWAITING_COUNTERPARTY
            - ON_HOLD
            - COMPLETED
            - FINISHED
            - CANCELLED
            - EXPIRED
            - COUNTERPARTY_MISMATCHED_DATA
            - COUNTERPARTY_VASP_NOT_FOUND
            - COUNTERPARTY_VASP_NOT_REACHABLE
            - UNCONFIRMED_OWNERSHIP
            - COUNTERPARTY_VASP_GENERAL_DECLINE
            - NOT_ENOUGH_COUNTERPARTY_DATA
            - NOT_APPLICABLE
        direction:
          type: string
          enum:
            - INBOUND
            - OUTBOUND
        rail:
          type: string
          nullable: true
          enum:
            - INTERNAL
            - TRP
            - GTR
            - TRUST
            - VERIFYVASP
            - SYGNA
            - EMAIL
            - TEST_VASP
            - null
          description: >-
            Le réseau sur lequel le transfert a été acheminé, ou null
            lorsqu'aucun réseau n'a été sélectionné (par exemple en dessous du
            seuil, un portefeuille de contrepartie auto-hébergé, un
            enregistrement après dépôt ou aucune contrepartie joignable).
            INTERNAL signifie que les deux parties sont des applications Didit ;
            EMAIL signifie que la contrepartie a été jointe via un lien de
            récupération envoyé par e-mail. TEST_VASP signifie que le VASP de
            test Didit a répondu au transfert sandbox. Sur GTR, VERIFYVASP et
            SYGNA, Didit lit la réponse de la contrepartie à partir de la
            réponse du réseau ou en l'interrogeant toutes les 5 minutes. TRUST
            effectue uniquement des envois, de sorte qu'un transfert TRUST reste
            à l'état AWAITING_COUNTERPARTY jusqu'à son expiration. Un canal de
            réseau n'est utilisé que si vous avez connecté votre propre adhésion
            à ce réseau. Il est choisi après le retour de la création de la
            transaction, il est donc null dans cette réponse.
        protocol:
          type: string
          nullable: true
        ivms_version:
          type: string
          example: ivms101.2023
        required:
          type: boolean
        ownership_confirmed:
          type: boolean
          nullable: true
        deadline_at:
          type: string
          format: date-time
          nullable: true
        timeline:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              at:
                type: string
                format: date-time
              detail:
                type: string
              name_match:
                allOf:
                  - $ref: '#/components/schemas/TravelRuleNameMatch'
                nullable: true
                description: >-
                  La comparaison de noms déterminée par cette entrée, à côté de
                  `detail`. Absente pour les entrées qui n'ont comparé aucun
                  nom.
              reason:
                type: string
                description: >-
                  Présent uniquement sur l'entrée d'une transition provoquée par
                  un échec de livraison : `email_undeliverable` ou
                  `delivery_failed`, la valeur indiquée par le `reason` du
                  transfert.
        counterparty_vasp:
          type: object
          nullable: true
          properties:
            name:
              type: string
            lei:
              type: string
            dd_score:
              type: integer
              description: >-
                Score de due diligence de 0 à 100, où une valeur plus élevée est
                meilleure. Même échelle que dans l'annuaire des VASP.
            dd_score_breakdown:
              type: object
              description: >-
                Contributions par composant au dd_score, un objet par composant
                comme dans le répertoire VASP (jurisdiction, verification,
                protocol, lei, history, essentials, responsiveness), chacun
                comprenant {points, max, reason, detail}. {} jusqu'à ce que la
                contrepartie ait été évaluée.
              additionalProperties:
                type: object
                properties:
                  points:
                    type: number
                    description: Points attribués pour ce composant.
                  max:
                    type: integer
                    description: Nombre maximal de points que ce composant peut attribuer.
                  reason:
                    type: string
                    description: Code lisible par machine du verdict du composant.
                  detail:
                    type: string
                    description: >-
                      Raison lisible par l'utilisateur pour les points
                      attribués.
            dd_assessed_at:
              type: string
              format: date-time
              nullable: true
              description: >-
                Date et heure de la dernière évaluation de diligence
                raisonnable. Null tant que la contrepartie n'a pas été évaluée.
        originator_data:
          type: object
          description: >-
            Partie du donneur d'ordre. Pour un transfert entrant, les valeurs de
            la contrepartie sont masquées jusqu'à ce que l'actionnariat soit
            confirmé.
        beneficiary_data:
          type: object
          description: >-
            Partie bénéficiaire. Pour un transfert entrant, les valeurs de la
            contrepartie sont masquées jusqu'à confirmation de la propriété.
        name_match:
          allOf:
            - $ref: '#/components/schemas/TravelRuleNameMatch'
          nullable: true
          description: "La comparaison de noms qui a déterminé le transfert, ou null tant qu'aucune n'a été exécutée. Lorsque les parties sont masquées, ainsi que sur la copie de l'autre client d'un échange INTERNAL, `transfer_name`, `compared_name`, `matched_names` et `mismatched_names` sont masqués. `score` et `matched` peuvent différer\_: `matched` suit le niveau d'exigence, `score` correspond à la similarité entre les deux noms complets."
        data_match:
          $ref: '#/components/schemas/TravelRuleDataMatch'
        mismatched_fields:
          type: array
          items:
            type: string
          description: >-
            Raccourci pour `data_match.mismatched_fields`. Vide lorsque rien ne
            diffère.
        data_unmasked:
          $ref: '#/components/schemas/TravelRuleDataUnmasked'
        data_masked:
          type: boolean
          description: >-
            Vrai tant que les données personnelles de la contrepartie sont
            masquées dans cette réponse.
        created_at:
          type: string
          format: date-time
        delivery:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TravelRuleDelivery'
          description: >-
            État d'acheminement du dernier message que ce transfert doit à
            l'autre partie. Vaut null lorsque le transfert n'a jamais dû en
            envoyer un (par exemple en dessous de `threshold_amount`, pour un
            portefeuille auto-hébergé déclaré ou un enregistrement sunrise).
        discovery:
          type: array
          description: >-
            Manière dont Didit a recherché la contrepartie, une entrée par étape
            exécutée. Vide lorsqu'aucune recherche n'a été effectuée, par
            exemple lors d'un transfert entrant.
          items:
            $ref: '#/components/schemas/TravelRuleDiscoveryStep'
        reason:
          type: string
          description: "Raison pour laquelle un transfert `COUNTERPARTY_VASP_NOT_FOUND` ou `COUNTERPARTY_VASP_NOT_REACHABLE` est bloqué\_; `\"\"` pour tout autre statut. Un échec de livraison la détermine en premier, sur `COUNTERPARTY_VASP_NOT_REACHABLE` uniquement\_: `email_undeliverable` (le fournisseur de messagerie a refusé l'e-mail de conformité et il ne reste aucune adresse à essayer\_: lors de son envoi, lors d'un rappel ou sous la forme d'un rejet permanent signalé ultérieurement) ou `delivery_failed` (le canal assurant la livraison a définitivement échoué\_: un canal réseau a refusé le message ou a épuisé ses tentatives, un hôte d'identité `TRP` n'a pas répondu, ou l'hôte `TRP` de la contrepartie n'a pas accepté la demande). Sinon, la trace `discovery` la détermine\_: `awaiting_end_user` (aucune étape n'a désigné de contrepartie que Didit peut joindre), `directory_match_no_route` (une étape a désigné un VASP de l'annuaire qui ne dispose d'aucun routage), `picked_member_without_proven_wallet` (l'utilisateur final a choisi un client Didit qui n'a pas prouvé le contrôle du portefeuille) ou `no_directory_match` lorsque la trace ne donne aucune autre raison. Un nouvel envoi fait progresser le transfert, ce qui efface le motif. Voir [Pourquoi un transfert est bloqué](/fr/transaction-monitoring/travel-rule#pourquoi-un-transfert-est-bloqué)."
        next_actions:
          type: array
          description: >-
            Ce qui permet de faire avancer le transfert ; `[]` pour tout statut
            autre que `COUNTERPARTY_VASP_NOT_FOUND` ou
            `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` propose
            `update_compliance_email`, puis `resend`. `delivery_failed` propose
            `resend`. Un motif lié à la découverte propose
            `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint`
            et `resend`.
          items:
            $ref: '#/components/schemas/TravelRuleNextAction'
        chain_details:
          $ref: '#/components/schemas/TravelRuleChainDetails'
    TravelRuleNameMatch:
      type: object
      nullable: true
      description: "La comparaison de noms qui a déterminé le transfert, ou null tant qu'aucune n'a été exécutée. Lorsque les parties sont masquées, ainsi que sur la copie de l'autre client d'un échange INTERNAL, `transfer_name`, `compared_name`, `matched_names` et `mismatched_names` sont masqués. `score` et `matched` peuvent différer\_: `matched` suit le niveau d'exigence, `score` correspond à la similarité entre les deux noms complets."
      properties:
        score:
          type: integer
          minimum: 0
          maximum: 100
          description: >-
            Similarité des deux noms complets, de 0 à 100. 0 si l'un des deux
            noms est vide.
        matched:
          type: boolean
          description: >-
            Indique si les noms satisfont à `strictness`. L'issue du transfert
            dépend de `data_match`, qui compare chaque champ ; un transfert peut
            donc être COUNTERPARTY_MISMATCHED_DATA alors que cette valeur est
            vraie.
        method:
          type: string
          enum:
            - none
            - exact_token
            - token_subset
            - token_containment
            - sequence_ratio
          description: >-
            Manière dont `matched` a été déterminé : none (`NONE`), exact_token
            (`STRICT`), token_subset (`DEFAULT`), token_containment (`CONTAINS`)
            ou sequence_ratio (`FUZZY`).
        strictness:
          type: string
          enum:
            - NONE
            - STRICT
            - CONTAINS
            - DEFAULT
            - FUZZY
        compared_with:
          type: string
          enum:
            - wallet_holder
            - counterparty_vasp
          description: >-
            wallet_holder : le titulaire enregistré pour le portefeuille.
            counterparty_vasp : le nom fourni par la contrepartie sur la page de
            réponse par e-mail, ou la réponse du VASP de test Didit dans le
            sandbox.
        transfer_name:
          type: string
          description: Le nom figurant sur le transfert.
        compared_name:
          type: string
          description: Le nom avec lequel il a été comparé.
        matched_names:
          type: array
          items:
            type: string
          description: Mots de `transfer_name` trouvés dans `compared_name`.
        mismatched_names:
          type: array
          items:
            type: string
          description: >-
            Mots de `transfer_name` absents de `compared_name`, puis mots de
            `compared_name` absents de `transfer_name`.
    TravelRuleDataMatch:
      type: object
      nullable: true
      description: >-
        Comparaison champ par champ des données des parties au transfert avec ce
        que l'autre partie sait du détenteur du portefeuille. Elle nomme les
        champs et les résultats, jamais les valeurs, afin de rester lisible
        pendant que les données de la contrepartie sont masquées. Null jusqu'à
        ce qu'une comparaison ait été exécutée.
      properties:
        matched:
          type: boolean
          description: Vrai lorsqu'aucun champ comparé ne diffère.
        mismatched_fields:
          type: array
          items:
            type: string
            enum:
              - name
              - date_of_birth
              - address
              - account
          description: Les champs qui diffèrent.
        fields:
          type: object
          description: >-
            Une entrée par champ comparé pour le type d'entité de la partie
            (`name`, `date_of_birth`, `address`, `account` ; une entreprise n'a
            pas de `date_of_birth`).
          additionalProperties:
            type: object
            properties:
              result:
                type: string
                enum:
                  - matched
                  - mismatched
                  - not_compared
                description: >-
                  `not_compared` lorsque la règle est `NONE` ou que l'un des
                  deux côtés ne comporte aucune valeur pour le champ.
              strictness:
                type: string
                enum:
                  - NONE
                  - STRICT
                  - CONTAINS
                  - DEFAULT
                  - FUZZY
    TravelRuleDataUnmasked:
      type: object
      nullable: true
      description: >-
        Enregistrement d'audit du moment où les données de la contrepartie ont
        été démasquées. Null tant que les données sont encore masquées, ainsi
        que pour les transferts sortants.
      properties:
        at:
          type: string
          format: date-time
        reason:
          type: string
          enum:
            - ownership_confirmed
            - wallet_proof
            - address_book_match
            - own_verified_wallet
            - inquiry_approved
            - known_payment_method
            - travel_address
          description: >-
            Ce qui a confirmé la propriété : ownership_confirmed (votre
            confirmation via la console ou l'API), wallet_proof (une preuve de
            portefeuille dans le widget, ou un transfert entrant INTERNAL,
            défini lors de sa création), address_book_match (un portefeuille
            vérifié du carnet d'adresses), own_verified_wallet (le portefeuille
            vérifié propre à votre utilisateur), inquiry_approved (votre
            approbation d'une demande TRP entrante ou d'un message GTR ou
            Sygna), known_payment_method (un portefeuille avec lequel votre
            utilisateur a déjà payé) ou travel_address (la Travel Address par
            portefeuille qui a nommé le portefeuille).
        actor:
          type: string
          description: >-
            Qui l'a confirmé : l'e-mail de l'utilisateur de la console ou le
            libellé de la clé API. Laissé vide pour une décision automatique.
    TravelRuleDelivery:
      type: object
      description: >-
        État d'acheminement du dernier message que le transfert doit à l'autre
        partie. Didit contacte la contrepartie après le retour de la requête
        ayant créé ou modifié le transfert ; cet objet indique donc si ce
        message a abouti : en file d'attente, en cours d'envoi, en attente de
        nouvelle tentative après une erreur, livré ou échoué. Une défaillance
        dont le réseau peut encore se remettre (absence de réponse dans les
        délais, échec de connexion, HTTP `408`, `429` ou `5xx`) fait l'objet
        d'une nouvelle tentative après 30 secondes, 2 minutes, 10 minutes, 30
        minutes et 1 heure. Lorsqu'un premier message (`kind: SEND`) échoue
        définitivement, parce que le réseau l'a refusé ou que la sixième
        tentative a également échoué, le transfert passe à
        `COUNTERPARTY_VASP_NOT_REACHABLE` avec `last_error` dans sa `timeline` ;
        tout autre message échouant définitivement est consigné dans la
        `timeline`. Le `status` du transfert demeure la source de vérité pour
        l'échange lui-même.
      required:
        - kind
        - status
        - rail
        - attempts
        - last_error
        - next_attempt_at
        - delivered_at
      properties:
        kind:
          type: string
          enum:
            - SEND
            - ANSWER
            - TXID
            - CANCEL
            - POLL
          description: >-
            Ce que transporte le message. `SEND` : le premier message du
            transfert destiné à la contrepartie (sortant ; le réseau est choisi
            lors de son envoi). `ANSWER` : votre acceptation ou votre refus, dû
            au réseau qui en a fait la demande (entrant). `TXID` : le hash de
            transaction on-chain, une fois que vous avez terminé le transfert.
            `CANCEL` : l'annulation, une fois que vous l'avez annulé. `POLL` :
            une requête de statut adressée à un réseau qui en propose une,
            répétée toutes les 5 minutes pendant que le transfert est en attente
            de la contrepartie.
        status:
          type: string
          enum:
            - QUEUED
            - SENDING
            - RETRYING
            - DELIVERED
            - FAILED
          description: >-
            `QUEUED` : en attente d'envoi. `SENDING` : une tentative est en
            cours. `RETRYING` : une tentative a échoué et la suivante
            s'exécutera à `next_attempt_at`. `DELIVERED` : l'autre partie a reçu
            le message. `FAILED` : l'autre partie l'a refusé, ou la dernière
            tentative a échoué.
        rail:
          type: string
          enum:
            - INTERNAL
            - TRP
            - GTR
            - TRUST
            - VERIFYVASP
            - SYGNA
            - EMAIL
            - ''
          description: >-
            Le canal qui achemine le message. Vide jusqu'à ce que Didit en ait
            choisi un pour un premier message.
        attempts:
          type: integer
          minimum: 0
          description: >-
            Tentatives effectuées jusqu'à présent pour ce message. Un message
            qui n'est pas un sondage d'état fait l'objet de 6 tentatives au
            maximum.
        last_error:
          type: string
          description: >-
            Le type d'échec rencontré lors de la dernière tentative, `""`
            lorsqu'il n'y en a eu aucun : par exemple `email undeliverable`,
            `trp identity endpoint unreachable` ou `trp transfer inquiry
            delivery failed`. Il ne contient jamais la propre réponse de la
            contrepartie, qui reste sur la `timeline` du transfert.

            Lorsque GTR répond par une erreur, son propre code d'état et son
            message sont inclus. Les corps de réponse ne sont jamais inclus.
          example: email undeliverable
        next_attempt_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Moment où la prochaine tentative s'exécute lorsque le message est
            `QUEUED` ou `RETRYING`.
        delivered_at:
          type: string
          format: date-time
          nullable: true
          description: Moment où l'autre partie a pris en charge le message.
    TravelRuleDiscoveryStep:
      type: object
      description: >-
        Une étape de la découverte de contrepartie exécutée par Didit pour un
        transfert sortant, dans l'ordre où elles ont été exécutées. La première
        étape qui désigne un VASP disposant d'une route met fin à la chaîne.
      properties:
        step:
          type: string
          enum:
            - internal_address_book
            - wallet_attribution
            - network_lookup
            - customer_hint
            - end_user
          description: >-
            `internal_address_book` : un autre client Didit ayant prouvé le
            contrôle du portefeuille de destination. `wallet_attribution` :
            l'attribution d'analyse blockchain du portefeuille. `network_lookup`
            : un réseau capable d'indiquer quel VASP détient l'adresse.
            `customer_hint` : le nom du VASP, le LEI ou la juridiction que vous
            avez indiqués dans `beneficiary_data`. `end_user` : la contrepartie
            choisie par l'utilisateur final (ou par vous), ou la demande d'en
            sélectionner une.
        outcome:
          type: string
          enum:
            - match
            - miss
            - skipped
          description: >-
            `match` : l'étape a identifié une contrepartie. `miss` : elle s'est
            exécutée et n'en a trouvé aucune. `skipped` : elle n'a pas pu
            s'exécuter, et `reason` en indique la raison.
        reason:
          type: string
          description: >-
            Raison lisible par machine, `""` en cas de correspondance :
            `no_proven_internal_wallet`, `attribution_disabled`,
            `already_attributed`, `no_attributed_entity`,
            `directory_match_no_route`, `gtr_address_lookup_runs_on_dispatch`,
            `no_membership`, `network_switched_off`,
            `no_network_address_lookup`, `no_directory_match`,
            `awaiting_end_user` ou `picked_member_without_proven_wallet`.
        vasp:
          type: string
          format: uuid
          nullable: true
          description: >-
            Le VASP de l'annuaire désigné par l'étape, lorsqu'elle en a désigné
            un.
        rail:
          type: string
          nullable: true
          description: >-
            Le canal qui permet d'atteindre cette contrepartie, lorsque l'étape
            en a trouvé un.
        at:
          type: string
          format: date-time
    TravelRuleNextAction:
      type: object
      description: >-
        Un élément permettant de faire avancer un transfert au statut
        `COUNTERPARTY_VASP_NOT_FOUND` ou `COUNTERPARTY_VASP_NOT_REACHABLE`.
        Consultez [Pourquoi un transfert est
        bloqué](/fr/transaction-monitoring/travel-rule#pourquoi-un-transfert-est-bloqué).
      properties:
        action:
          type: string
          enum:
            - select_counterparty_vasp
            - declare_self_hosted
            - add_vasp_hint
            - update_compliance_email
            - resend
          description: >-
            `select_counterparty_vasp` : l'utilisateur final choisit le VASP de
            destination dans le widget de possession de portefeuille, ou vous
            effectuez un PATCH avec `action=beneficiary_vasp`.
            `declare_self_hosted` : l'utilisateur final déclare le portefeuille
            comme auto-hébergé dans le widget. `add_vasp_hint` : indiquez à
            Didit qui est la contrepartie, avec un nom de VASP, un LEI ou une
            Travel Address (par exemple une `travel_address` sur l'entrée du
            carnet d'adresses du portefeuille de destination), puis renvoyez.
            `update_compliance_email` et `resend` sont des valeurs de `action`
            pour `PATCH /v3/transactions/{transaction_id}/travel-rule/` :
            fournissez à nouveau l'e-mail de conformité de la contrepartie, et
            relancez le routage.
        url:
          type: string
          format: uri
          description: >-
            Le lien du widget de propriété du portefeuille, pour
            `select_counterparty_vasp` et `declare_self_hosted` tant que le
            transfert a une session de widget ouverte.
      required:
        - action
    TravelRuleChainDetails:
      type: object
      description: >-
        Manière dont la blockchain du transfert nomme ses deux portefeuilles,
        lorsque plus d'une adresse en paie une autre. Vide (`{}`) pour un
        transfert sur une blockchain basée sur des comptes (EVM, Solana, Tron),
        où les deux adresses sont les portefeuilles. La correspondance, le
        routage et le carnet d'adresses lisent d'abord les portefeuilles ici.
      properties:
        chain:
          type: string
          description: >-
            Blockchain canonique, par ex. `BTC`, `XRP`, ou `LIGHTNING` pour un
            transfert Lightning.
        shape:
          type: string
          enum:
            - utxo
            - memo
            - lightning
        originator:
          $ref: '#/components/schemas/TravelRuleChainSide'
        beneficiary:
          $ref: '#/components/schemas/TravelRuleChainSide'
        utxo:
          type: object
          description: >-
            Sur un transfert UTXO : les entrées et sorties telles
            qu'enregistrées (montants sous forme de chaînes décimales) et la
            manière dont Didit a interprété chaque sortie.
          properties:
            inputs:
              type: array
              items:
                $ref: '#/components/schemas/TravelRuleUtxoEntry'
            outputs:
              type: array
              items:
                $ref: '#/components/schemas/TravelRuleUtxoEntry'
            change_output_indexes:
              type: array
              items:
                type: integer
              description: Sorties qui remboursent une adresse d'entrée.
            beneficiary_output_index:
              type: integer
              nullable: true
              description: "La sortie qui paie le bénéficiaire\_; null lorsqu'aucune n'a pu être distinguée."
        lightning:
          type: object
          description: >-
            Sur un transfert Lightning : ce qu'indique la demande de paiement.
            Toujours `kind` (`bolt11`, `bolt12_offer`, `bolt12_invoice`,
            `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id` ou
            `unknown`) ; une facture BOLT11 ajoute `network`, `payee_node_id`,
            `payment_hash`, `amount_msat`, `created_at` et `expires_at` ; une
            chaîne BOLT12 ajoute `blinded_paths` et `payee_node_id` ; un LNURL
            ou une adresse Lightning ajoute son `domain`. Rien n'est résolu sur
            le réseau : la requête est uniquement décodée.
          additionalProperties: true
        warnings:
          type: array
          items:
            type: string
            enum:
              - declared_originator_not_an_input
              - declared_beneficiary_not_an_output
              - beneficiary_output_ambiguous
              - beneficiary_output_amount_differs
          description: >-
            Incohérences UTXO nécessitant une vérification : le donneur d'ordre
            déclaré n'est pas une entrée, le bénéficiaire déclaré n'est pas une
            sortie, aucune sortie de bénéficiaire unique n'a pu être distinguée,
            ou la sortie du bénéficiaire paie un montant différent de celui
            indiqué par la transaction.
        not_applicable_reason:
          type: string
          enum:
            - LIGHTNING_NO_PAYEE_IDENTIFIER
            - LIGHTNING_BOLT12_BLINDED_PAYEE
            - LIGHTNING_LNURL_NAMES_NO_PAYEE
          description: >-
            Sur un transfert Lightning sortant dont la demande de paiement ne
            mentionne aucun bénéficiaire : pourquoi le transfert est
            `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (la demande ne
            mentionne aucun nœud bénéficiaire ou n'a pas pu être décodée),
            `LIGHTNING_BOLT12_BLINDED_PAYEE` (l'offre dissimule son bénéficiaire
            derrière des chemins aveugles), `LIGHTNING_LNURL_NAMES_NO_PAYEE` (un
            LNURL désigne un service, pas un bénéficiaire). Le même code ouvre
            la dernière entrée de la `timeline` du transfert.
    TravelRuleChainSide:
      type: object
      description: >-
        Le portefeuille de l'une des parties, tel que Didit l'a résolu à partir
        des données de la blockchain.
      properties:
        address:
          type: string
          description: >-
            Le portefeuille. Sur un réseau à mémo, l'adresse classique (une
            X-address XRP est divisée en son adresse classique et son tag) ; sur
            Lightning, l'identifiant du nœud du bénéficiaire ou la Lightning
            Address.
        memo:
          type: string
          description: >-
            Le tag de destination ou mémo faisant partie du portefeuille ; `""`
            en l'absence de mémo.
        source:
          type: string
          enum:
            - declared
            - x_address
            - largest_input
            - only_non_change_output
            - amount_match
            - invoice_payee
            - updated
          description: >-
            Origine du portefeuille : `declared` (votre requête), `x_address`
            (dérivée d'une adresse X XRP), `largest_input` (l'adresse d'entrée
            UTXO ayant le plus contribué), `only_non_change_output` (la seule
            sortie UTXO qui n'est pas de la monnaie rendue), `amount_match`
            (l'unique sortie UTXO payant le montant du transfert),
            `invoice_payee` (le bénéficiaire désigné par une demande de paiement
            Lightning), `updated` (défini ultérieurement avec `action:
            update_originator_wallet`).
    TravelRuleUtxoEntry:
      type: object
      description: >-
        Une entrée ou une sortie d'une transaction UTXO, telle qu'enregistrée
        par la blockchain.
      required:
        - address
      properties:
        address:
          type: string
          maxLength: 128
        amount:
          type: string
          nullable: true
          description: >-
            Chaîne décimale dans l'unité propre à la crypto-monnaie (BTC, et non
            en satoshis). Facultatif.
          example: '0.0125'
        txid:
          type: string
          maxLength: 128
          description: Facultatif. La transaction dépensée par une entrée.
        vout:
          type: integer
          nullable: true
          minimum: 0
          description: Facultatif. L'index de sortie dépensé par une entrée.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clé API de votre application, issue de Développeurs -> Clés API dans
        la Business Console. La clé principale dispose d'un accès complet. Une
        clé nommée peut être restreinte : aucun, lecture ou écriture par
        ressource, limitée à certains workflows ou aux sessions approuvées, à
        une liste d'adresses IP et à une date d'expiration. 401 signifie que la
        clé est incorrecte, révoquée ou expirée ; 403 signifie qu'aucune clé n'a
        été envoyée, que la clé n'a pas accès à cette ressource ou action, ou
        que la requête provient d'une adresse hors de sa liste d'IP ; 404 sur
        une route de session signifie que la session est hors des workflows ou
        des statuts de la clé. Une clé sans accès aux médias reçoit les URL
        d'images, de vidéos et de PDF à null, et une clé sans accès en écriture
        aux sessions reçoit les liens et tokens de session à null. Voir
        https://docs.didit.me/console/api-keys.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.