> ## 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.

# API Travel Rule: completare, reinviare, aggiornare

> Con Didit chiudi un trasferimento Travel Rule con l'hash on-chain, annullalo, reinvialo o registra il wallet di partenza effettivo.



Prompt dell'API per le azioni di trasferimento della Travel Rule
        Copia il prompt negli appunti



      
      

\<pre>

\`Act on an existing Travel Rule transfer: report the on-chain hash to finish it, cancel it, re-run counterparty routing, replace a refused compliance email, or record the wallet the funds left from.

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

Authentication:
Use the x-api-key header with my Didit API key. {transaction_id} is the Didit transaction uuid.

Four mutually exclusive bodies:

1\. Finish (close out after broadcasting on-chain):
\{"payment_txn_id": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"}
\- Requires an OUTBOUND transfer in COMPLETED status - otherwise 409.
\- Moves the transfer (and its INTERNAL-rail counterpart, if any) to FINISHED and stores the hash on the transaction.
\- Over GTR, VerifyVASP or Sygna Bridge, the network learns the hash after the response, with retries (see delivery below).
\- On the TRP rail, Didit also posts the hash to the counterparty's confirmation callback.

2\. Cancel:
\{"action": "cancel"}
\- Allowed from any non-terminal status; moves the transfer (and its INTERNAL-rail counterpart, if any) to CANCELLED.
\- From a terminal status (FINISHED, CANCELLED, EXPIRED) it returns 409.
\- On an outbound TRP transfer, Didit also sends a cancellation to the counterparty.
\- Over GTR, VerifyVASP or Sygna Bridge, the network is told after the response, with retries.

3\. Resend (re-run the routing ladder):
\{"action": "resend"}
\- Allowed only on an OUTBOUND transfer in COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, or NOT_ENOUGH_COUNTERPARTY_DATA - otherwise 409.
\- Resets the deadline and re-runs routing; a transfer whose destination wallet was declared unhosted moves to UNCONFIRMED_OWNERSHIP.
\- First give Didit a route, for example by registering the destination wallet in your address book (same chain as the transfer, or a blank chain) with the counterparty's travel_address (TRP carries BTC, ETH, and USDC on a named network), or by adding a compliance contact for the counterparty's directory entry with POST /v3/travel-rule/counterparty-contacts/, then resend.
\- Resend reuses the transfer's beneficiary_data, which you cannot change after creation except for the compliance email (body 4), so submit a new transaction to send different beneficiary data.
\- A previously recorded blockchain-analytics attribution is reused - no new lookup, no new charge.
\- Discovery runs again from the first step (internal address book, wallet attribution, network lookup, your VASP hint, then the end user); the transfer's "discovery" list shows what each step found.
\- Queued, not run inside the request: the response shows the transfer back in AWAITING_COUNTERPARTY with a "resend queued" timeline entry, and the outcome arrives as a travel_rule.status.updated webhook. A resend sent while an earlier attempt is still running is sent once that attempt settles.
\- If routing still resolves nothing, the transfer lands back in COUNTERPARTY_VASP_NOT_FOUND.

4\. Update the compliance email (the fix for reason email_undeliverable):
\{"action": "update_compliance_email", "compliance_email": "desk@bene-casp.example"}
\- Allowed only on an OUTBOUND transfer in COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, or NOT_ENOUGH_COUNTERPARTY_DATA - otherwise 409.
\- A missing or malformed compliance_email returns 400.
\- Stores the address as this transfer's beneficiary_data.counterparty_vasp_email; it belongs to this transfer only and joins no directory entry or contact list.
\- The status does not change and the timeline gains "compliance email updated". The transfer keeps reason email_undeliverable until you send {"action": "resend"}, which sends the request to the new address.

4\. Update the originator wallet (the wallet the funds actually left from):
\{"action": "update_originator_wallet", "wallet_address": "bc1q...", "memo": ""}
\- Outbound transfers only (an inbound transfer -> 409), and never a CANCELLED or EXPIRED one (-> 409).
\- Use it when a withdrawal is broadcast from another address than the one declared, typically a UTXO withdrawal spending whichever addresses held the coins. When the transfer's UTXO inputs are known, wallet_address must be one of them (-> 400 otherwise).
\- Changes the record only: nothing is sent to the counterparty again and the status stays. chain_details.originator becomes the new wallet with source "updated", the timeline records the previous and the new wallet, and the INTERNAL-rail counterpart is updated the same way.

5\. Name the counterparty (when discovery could not):
\{"action": "beneficiary_vasp", "beneficiary_vasp": "<directory VASP id>"}
\- The id comes from GET /v3/travel-rule/vasps/.
\- Allowed only for an outbound transfer in COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, or NOT_ENOUGH_COUNTERPARTY_DATA - otherwise 409.
\- Routes the transfer to that VASP and sends it again; automatic discovery never overrides your choice.
\- 400 if beneficiary_vasp is missing or not a valid id, 404 if no directory entry has that id.

What to read from the response:
\- The full transfer object: status, rail, direction, ownership_confirmed, deadline_at, timeline, counterparty_vasp, delivery, discovery, reason, next_actions.
\- delivery: the latest message the transfer owes the other side - kind (SEND, ANSWER, TXID, CANCEL, POLL), status (QUEUED, SENDING, RETRYING, DELIVERED, FAILED), rail, attempts, last_error, next_attempt_at, delivered_at. Failures a network may recover from are retried after 30 s, 2, 10, 30 and 60 minutes; when a first message fails for good the transfer moves to COUNTERPARTY_VASP_NOT_REACHABLE. null when the transfer never owed a message.
\- reason and next_actions say why a COUNTERPARTY_VASP_NOT_FOUND or COUNTERPARTY_VASP_NOT_REACHABLE transfer is stuck and what moves it on: email_undeliverable offers update_compliance_email then resend, delivery_failed offers resend, and a discovery reason offers select_counterparty_vasp, declare_self_hosted, add_vasp_hint and resend. Both are empty for any other status, so they clear once a resend moves the transfer on.

Order of operations for outbound transfers:
submit transaction -> wait for travel_rule.status == "COMPLETED" -> broadcast on-chain -> PATCH with payment_txn_id -> FINISHED.
Never broadcast before COMPLETED.
A transfer sent over TRUST cannot reach COMPLETED, because TRUST sends back nothing Didit can read; it stays AWAITING_COUNTERPARTY until it expires. Over GTR, VerifyVASP and Sygna Bridge, Didit reads the counterparty's answer from the network.
If the message cannot be delivered, the transfer moves to COUNTERPARTY_VASP_NOT_REACHABLE instead.

Failure modes:
\- 400 - the body has none of payment_txn_id or a supported action, update_compliance_email has a missing or malformed compliance_email, or a wallet_address or memo the transfer's chain cannot carry.
\- 409 - action not allowed from the transfer's current status or direction (see the per-action rules above).
\- 400 - action=beneficiary_vasp without a valid beneficiary_vasp.
\- 404 - unknown transaction, no Travel Rule transfer attached, or (action=beneficiary_vasp) no directory entry has that id.

Full guide: /transaction-monitoring/travel-rule#sending-a-transfer and /transaction-monitoring/travel-rule#why-a-transfer-is-stuck.`

\</pre>



      
      

Incolla in



## OpenAPI

````yaml it/openapi-25.json PATCH /v3/transactions/{transaction_id}/travel-rule/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API di verifica dell'identità. Autenticati con l'intestazione x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/transactions/{transaction_id}/travel-rule/:
    patch:
      tags:
        - Travel Rule
      summary: >-
        Concludi, annulla, invia nuovamente o aggiorna il wallet dell'ordinante
        di un trasferimento Travel Rule
      description: >-
        Fornisci `payment_txn_id` per comunicare l'hash on-chain e spostare un
        trasferimento in uscita da COMPLETED a FINISHED (anche la sua
        controparte su canale INTERNAL passa a FINISHED), `{"action": "cancel"}`
        per annullare un trasferimento non terminale, oppure `{"action":
        "resend"}` per instradare nuovamente un trasferimento in uscita bloccato
        in COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE o
        NOT_ENOUGH_COUNTERPARTY_DATA (migliora prima i dati della controparte,
        ad es. aggiungendo un travel_address alla voce del wallet di
        destinazione). resend si applica solo ai trasferimenti in uscita.
        `{"action": "update_compliance_email", "compliance_email":
        "desk@example.com"}` sostituisce l'email di compliance di un
        trasferimento in uscita in uno di questi tre stati, la soluzione per
        `reason: email_undeliverable`: lo stato non cambia e il successivo
        `resend` invia la richiesta a quell'indirizzo. Un nuovo invio viene
        accodato, non eseguito all'interno della richiesta: la risposta mostra
        il trasferimento di nuovo in AWAITING_COUNTERPARTY con una voce `resend
        queued` nella timeline e una `delivery` in coda, e la destinazione
        raggiunta viene notificata tramite un webhook
        `travel_rule.status.updated`. Quando il trasferimento è passato tramite
        GTR, VerifyVASP o Sygna Bridge, la rete riceve l'hash on-chain o
        l'annullamento dopo la risposta, con nuovi tentativi; `delivery` mostra
        lo stato di quel messaggio. `{"action": "update_originator_wallet",
        "wallet_address": "..."}` registra il wallet da cui sono effettivamente
        partiti i fondi per un trasferimento in uscita, ad esempio l'indirizzo
        da cui è stato trasmesso un prelievo UTXO anziché il wallet principale
        dichiarato. Modifica solo la registrazione: non viene inviato nuovamente
        nulla alla controparte e lo stato rimane invariato. L'ordinante diventa
        `chain_details.originator` con `source: updated`, la modifica viene
        aggiunta alla `timeline` con il wallet precedente e quello nuovo, e la
        controparte su canale INTERNAL del trasferimento viene aggiornata nello
        stesso modo. `{"action": "beneficiary_vasp", "beneficiary_vasp":
        "<directory VASP id>"}` indica direttamente la controparte quando il
        rilevamento automatico non è riuscito, su un trasferimento in uscita in
        COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE o
        NOT_ENOUGH_COUNTERPARTY_DATA: il trasferimento viene instradato verso
        quel VASP e inviato nuovamente.
      operationId: patchTravelRuleTransfer
      parameters:
        - name: transaction_id
          in: path
          required: true
          description: >-
            UUID della transazione stabile di Didit a cui appartiene il
            trasferimento.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TravelRuleTransferPatchRequest'
            examples:
              Finish:
                value:
                  payment_txn_id: 0xchainhash
              Cancel:
                value:
                  action: cancel
              Resend:
                value:
                  action: resend
              Update compliance email:
                value:
                  action: update_compliance_email
                  compliance_email: desk@example.com
              Update originator wallet:
                value:
                  action: update_originator_wallet
                  wallet_address: bc1qOriginatorInputAddress01
              Name the counterparty:
                value:
                  action: beneficiary_vasp
                  beneficiary_vasp: 9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607
      responses:
        '200':
          description: >-
            Il trasferimento aggiornato. Dopo `update_compliance_email`, il suo
            stato rimane invariato e mantiene `reason: email_undeliverable` fino
            al successivo `resend`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelRuleTransferDetail'
        '400':
          description: >-
            Non è stato fornito né payment_txn_id né un'azione supportata,
            `compliance_email` è mancante o non è un indirizzo email su
            `update_compliance_email`, oppure, per `update_originator_wallet`,
            manca wallet_address, è presente un wallet o memo non supportato
            dalla blockchain del trasferimento, o un wallet che non fa parte
            degli input UTXO del trasferimento, oppure `beneficiary_vasp` è
            mancante o non è un ID VASP valido della directory.
          content:
            application/json:
              examples:
                No action:
                  value:
                    detail:
                      - >-
                        Provide payment_txn_id, action=cancel, action=resend,
                        action=beneficiary_vasp, action=update_originator_wallet
                        or action=update_compliance_email.
                Invalid compliance email:
                  value:
                    compliance_email:
                      - Enter a valid email address.
        '404':
          description: >-
            Transazione sconosciuta, la transazione non contiene alcun
            trasferimento Travel Rule oppure (azione `beneficiary_vasp`) nessuna
            voce della directory ha quell'id.
        '409':
          description: >-
            Il trasferimento non si trova in uno stato che consente questa
            operazione (ad es. non COMPLETED/in uscita per finish, già in stato
            finale per cancel, oppure non un trasferimento in uscita in uno
            stato reinviabile per resend). `update_compliance_email` risponde
            con `409` per un trasferimento in entrata, e per uno in uscita al di
            fuori di COUNTERPARTY_VASP_NOT_FOUND,
            COUNTERPARTY_VASP_NOT_REACHABLE e NOT_ENOUGH_COUNTERPARTY_DATA.
            `update_originator_wallet` risponde con `409` per un trasferimento
            in entrata, annullato o scaduto. `beneficiary_vasp` risponde con
            `409` a meno che il trasferimento non sia in uscita e in
            COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE o
            NOT_ENOUGH_COUNTERPARTY_DATA.
          content:
            application/json:
              examples:
                Cancel from a terminal status:
                  value:
                    detail: Transfer is already in a terminal state.
                Resend not allowed:
                  value:
                    detail: Transfer cannot be resent from its current state.
                Finish not allowed:
                  value:
                    detail: >-
                      Transfer must be an outbound transfer in COMPLETED status
                      to finish.
                Compliance email cannot change:
                  value:
                    detail: >-
                      The compliance email of this transfer cannot change from
                      its current state.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            curl -X PATCH
            https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/
            \
              -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \
              -d '{"payment_txn_id": "0xchainhash"}'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.transactions.travel_rule.update_transfer(
                "11111111-2222-3333-4444-555555555555",
                payment_txn_id="0xchainhash",
            )
            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.updateTransfer("11111111-2222-3333-4444-555555555555",
            {
              payment_txn_id: "0xchainhash",
            });

            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.UpdateTransfer(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleTransferPatchRequest{\n\tPaymentTxnID: didit.String(\"0xchainhash\"),\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.TravelRuleTransferPatchRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.transactions().travelRule().updateTransfer("11111111-2222-3333-4444-555555555555",
            TravelRuleTransferPatchRequest.builder()
                    .paymentTxnId("0xchainhash")
                    .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->updateTransfer('11111111-2222-3333-4444-555555555555',
            [
                'payment_txn_id' => '0xchainhash',
            ]);

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

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

            result = didit.transactions.travel_rule.update_transfer(
              "11111111-2222-3333-4444-555555555555",
              payment_txn_id: "0xchainhash"
            )
            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.UpdateTransferAsync("11111111-2222-3333-4444-555555555555",
            new TravelRuleTransferPatchRequest

            {
                PaymentTxnId = "0xchainhash",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    TravelRuleTransferPatchRequest:
      type: object
      description: >-
        Fornisci esattamente uno tra: payment_txn_id (finish), action=cancel,
        action=resend, action=update_compliance_email con compliance_email,
        action=update_originator_wallet con wallet_address o
        action=beneficiary_vasp con beneficiary_vasp.
      properties:
        payment_txn_id:
          type: string
          description: >-
            L'hash della transazione on-chain. Richiede che il trasferimento sia
            un trasferimento in uscita con stato COMPLETED.
        action:
          type: string
          enum:
            - cancel
            - resend
            - update_compliance_email
            - update_originator_wallet
            - beneficiary_vasp
          description: >-
            "cancel" annulla un trasferimento non definitivo. "resend" esegue
            nuovamente l'instradamento per un trasferimento in uscita bloccato
            in COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE o
            NOT_ENOUGH_COUNTERPARTY_DATA. "update_compliance_email" sostituisce
            l'email di compliance a cui viene inviata la richiesta, per un
            trasferimento in uscita in uno di questi tre stati; invia
            successivamente "resend". "update_originator_wallet" registra il
            wallet da cui sono effettivamente partiti i fondi (`wallet_address`,
            `memo`). "beneficiary_vasp" indica direttamente il VASP di
            controparte (richiede `beneficiary_vasp`) per un trasferimento in
            uscita in uno di questi stati: viene instradato verso quel VASP e
            inviato di nuovo.
        compliance_email:
          type: string
          format: email
          maxLength: 254
          description: >-
            Obbligatorio con `action: update_compliance_email`. Mantenuto come
            `beneficiary_data.counterparty_vasp_email` di questo trasferimento:
            appartiene esclusivamente a questo trasferimento e non viene
            aggiunto a nessuna voce di directory né ad alcuna lista di contatti.
        wallet_address:
          type: string
          maxLength: 128
          description: >-
            Con `action: update_originator_wallet`: il wallet da cui sono
            partiti i fondi. Quando gli input UTXO del trasferimento sono noti,
            deve essere uno di essi.
        memo:
          type: string
          maxLength: 256
          description: >-
            Con `action: update_originator_wallet`: il memo o tag del wallet su
            una rete memo. Opzionale.
        beneficiary_vasp:
          type: string
          format: uuid
          description: >-
            Obbligatorio con action=beneficiary_vasp: l'`id` di un VASP della
            directory, ottenuto da `GET /v3/travel-rule/vasps/`. La tua scelta
            ha la priorità su ogni passaggio di rilevamento automatico, che non
            la sovrascrive mai.
    TravelRuleTransferDetail:
      type: object
      description: >-
        Oggetto di trasferimento completo restituito dagli endpoint di conferma
        della titolarità e di completamento/annullamento. Finché la titolarità
        del wallet di un trasferimento in entrata non è confermata, i campi
        `originator_data` e `beneficiary_data` della controparte vengono
        restituiti mascherati (viene mantenuta la prima lettera di ogni parola;
        il wallet, la chain e l'instradamento VASP rimangono leggibili) e
        `data_masked` è 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: >-
            Il canale (rail) su cui è stato instradato il trasferimento, o null
            quando non è stato selezionato alcun canale (ad esempio sotto la
            soglia, un wallet della controparte in autocustodia, una
            registrazione post-deposito o nessuna controparte raggiungibile).
            INTERNAL indica che entrambe le parti sono applicazioni Didit; EMAIL
            indica che la controparte è stata raggiunta tramite un link di
            ritiro inviato via email. TEST_VASP indica che il Didit Test VASP ha
            risposto al trasferimento sandbox. Tramite GTR, VERIFYVASP e SYGNA,
            Didit legge la risposta della controparte dalla risposta della rete
            o effettuando un polling ogni 5 minuti. TRUST invia soltanto, quindi
            un trasferimento TRUST rimane AWAITING_COUNTERPARTY fino alla
            scadenza. Un canale di rete viene utilizzato solo dopo aver
            collegato la propria iscrizione per tale rete. Viene scelto dopo che
            la creazione della transazione ha restituito risposta, quindi è null
            in tale risposta.
        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: >-
                  Il confronto dei nomi che ha determinato questa voce, accanto
                  a `detail`. Assente nelle voci che non hanno confrontato alcun
                  nome.
              reason:
                type: string
                description: >-
                  Presente solo sulla voce di una transizione causata da una
                  mancata consegna: `email_undeliverable` o `delivery_failed`,
                  il valore riportato da `reason` del trasferimento.
        counterparty_vasp:
          type: object
          nullable: true
          properties:
            name:
              type: string
            lei:
              type: string
            dd_score:
              type: integer
              description: >-
                Punteggio di due diligence da 0 a 100, dove un valore più alto è
                migliore. Stessa scala utilizzata nella directory dei VASP.
            dd_score_breakdown:
              type: object
              description: >-
                Contributi per componente a dd_score, un oggetto per componente
                come nella directory VASP (giurisdizione, verifica, protocollo,
                lei, cronologia, elementi essenziali, reattività), ciascuno con
                {points, max, reason, detail}. {} finché la controparte non è
                stata valutata.
              additionalProperties:
                type: object
                properties:
                  points:
                    type: number
                    description: Punti assegnati per questo componente.
                  max:
                    type: integer
                    description: Punti massimi che questo componente può assegnare.
                  reason:
                    type: string
                    description: Codice leggibile dalla macchina dell'esito del componente.
                  detail:
                    type: string
                    description: Motivo leggibile dall'utente per i punti assegnati.
            dd_assessed_at:
              type: string
              format: date-time
              nullable: true
              description: >-
                Data e ora dell'ultima esecuzione della valutazione di adeguata
                verifica. Null finché la controparte non è stata valutata.
        originator_data:
          type: object
          description: >-
            Soggetto ordinante. Per un trasferimento in entrata, i valori della
            controparte sono oscurati fino alla conferma dell'assetto
            proprietario.
        beneficiary_data:
          type: object
          description: >-
            Parte beneficiaria. Per un trasferimento in entrata i valori della
            controparte sono mascherati fino a quando non viene confermato
            l'assetto proprietario.
        name_match:
          allOf:
            - $ref: '#/components/schemas/TravelRuleNameMatch'
          nullable: true
          description: >-
            Il confronto dei nomi che ha determinato il trasferimento, o null
            fino all'esecuzione. Mentre le parti sono oscurate, e sulla copia
            dell'altro cliente di uno scambio INTERNAL, `transfer_name`,
            `compared_name`, `matched_names` e `mismatched_names` rimangono
            nascosti. `score` e `matched` possono discordare: `matched` segue il
            livello di rigore, `score` è la somiglianza dei due nomi completi.
        data_match:
          $ref: '#/components/schemas/TravelRuleDataMatch'
        mismatched_fields:
          type: array
          items:
            type: string
          description: >-
            Scorciatoia per `data_match.mismatched_fields`. Vuoto quando non ci
            sono differenze.
        data_unmasked:
          $ref: '#/components/schemas/TravelRuleDataUnmasked'
        data_masked:
          type: boolean
          description: >-
            True mentre i dati personali della controparte sono mascherati in
            questa risposta.
        created_at:
          type: string
          format: date-time
        delivery:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TravelRuleDelivery'
          description: >-
            Lo stato dell'ultimo messaggio dovuto da questo trasferimento alla
            controparte. Null quando il trasferimento non ha mai dovuto inviarne
            uno (ad esempio al di sotto di `threshold_amount`, un wallet in
            autocustodia dichiarato o una registrazione sunrise).
        discovery:
          type: array
          description: >-
            Modalità con cui Didit ha cercato la controparte, una voce per ogni
            passaggio eseguito. Vuoto se non è stata eseguita alcuna ricerca, ad
            esempio per un trasferimento in entrata.
          items:
            $ref: '#/components/schemas/TravelRuleDiscoveryStep'
        reason:
          type: string
          description: >-
            Il motivo per cui un trasferimento `COUNTERPARTY_VASP_NOT_FOUND` o
            `COUNTERPARTY_VASP_NOT_REACHABLE` è bloccato; `""` per qualsiasi
            altro stato. Una consegna non riuscita lo determina per prima, solo
            su `COUNTERPARTY_VASP_NOT_REACHABLE`: `email_undeliverable` (il
            provider di posta ha rifiutato l'email di compliance e non è rimasto
            alcun indirizzo da provare: quando è stata inviata, in un promemoria
            o come bounce permanente segnalato successivamente) o
            `delivery_failed` (il canale che effettuava la consegna è fallito
            definitivamente: un canale di rete ha rifiutato il messaggio o ha
            esaurito i tentativi, un host di identità `TRP` non ha risposto o
            l'host `TRP` della controparte non ha accettato la richiesta).
            Altrimenti lo determina la traccia di `discovery`:
            `awaiting_end_user` (nessun passaggio ha indicato una controparte
            raggiungibile da Didit), `directory_match_no_route` (un passaggio ha
            indicato un VASP della directory privo di rotta),
            `picked_member_without_proven_wallet` (l'utente finale ha scelto un
            cliente Didit che non ha dimostrato il controllo del wallet) o
            `no_directory_match` quando la traccia non fornisce altri motivi. Un
            nuovo invio fa avanzare il trasferimento, quindi il motivo viene
            azzerato. Consulta [Perché un trasferimento è
            bloccato](/it/transaction-monitoring/travel-rule#perché-un-trasferimento-è-bloccato).
        next_actions:
          type: array
          description: >-
            Cosa fa procedere il trasferimento; `[]` per qualsiasi stato tranne
            `COUNTERPARTY_VASP_NOT_FOUND` o `COUNTERPARTY_VASP_NOT_REACHABLE`.
            `email_undeliverable` propone `update_compliance_email`, poi
            `resend`. `delivery_failed` propone `resend`. Un motivo di discovery
            propone `select_counterparty_vasp`, `declare_self_hosted`,
            `add_vasp_hint` e `resend`.
          items:
            $ref: '#/components/schemas/TravelRuleNextAction'
        chain_details:
          $ref: '#/components/schemas/TravelRuleChainDetails'
    TravelRuleNameMatch:
      type: object
      nullable: true
      description: >-
        Il confronto dei nomi che ha determinato il trasferimento, o null fino
        all'esecuzione. Mentre le parti sono oscurate, e sulla copia dell'altro
        cliente di uno scambio INTERNAL, `transfer_name`, `compared_name`,
        `matched_names` e `mismatched_names` rimangono nascosti. `score` e
        `matched` possono discordare: `matched` segue il livello di rigore,
        `score` è la somiglianza dei due nomi completi.
      properties:
        score:
          type: integer
          minimum: 0
          maximum: 100
          description: >-
            Somiglianza dei due nomi completi, da 0 a 100. 0 quando uno dei due
            nomi è vuoto.
        matched:
          type: boolean
          description: >-
            Indica se i nomi soddisfano `strictness`. L'esito del trasferimento
            segue `data_match`, che confronta ogni campo, pertanto un
            trasferimento può essere COUNTERPARTY_MISMATCHED_DATA anche quando
            questo valore è true.
        method:
          type: string
          enum:
            - none
            - exact_token
            - token_subset
            - token_containment
            - sequence_ratio
          description: >-
            Modalità con cui è stato determinato `matched`: nessuno (`NONE`),
            exact_token (`STRICT`), token_subset (`DEFAULT`), token_containment
            (`CONTAINS`) o sequence_ratio (`FUZZY`).
        strictness:
          type: string
          enum:
            - NONE
            - STRICT
            - CONTAINS
            - DEFAULT
            - FUZZY
        compared_with:
          type: string
          enum:
            - wallet_holder
            - counterparty_vasp
          description: >-
            wallet_holder: il titolare registrato per il wallet.
            counterparty_vasp: il nome indicato dalla controparte nella pagina
            di risposta via email, o la risposta di Didit Test VASP in sandbox.
        transfer_name:
          type: string
          description: Il nome sul trasferimento.
        compared_name:
          type: string
          description: Il nome con cui è stato confrontato.
        matched_names:
          type: array
          items:
            type: string
          description: Parole di `transfer_name` trovate in `compared_name`.
        mismatched_names:
          type: array
          items:
            type: string
          description: >-
            Parole di `transfer_name` mancanti da `compared_name`, seguite dalle
            parole di `compared_name` mancanti da `transfer_name`.
    TravelRuleDataMatch:
      type: object
      nullable: true
      description: >-
        Confronto campo per campo tra i dati della parte del trasferimento e ciò
        che l'altra parte sa sul titolare del wallet. Riporta i nomi dei campi e
        i risultati, mai i valori, in modo che rimanga leggibile mentre i dati
        della controparte sono oscurati. Null finché non viene eseguito un
        confronto.
      properties:
        matched:
          type: boolean
          description: True quando nessun campo confrontato differisce.
        mismatched_fields:
          type: array
          items:
            type: string
            enum:
              - name
              - date_of_birth
              - address
              - account
          description: I campi che differiscono.
        fields:
          type: object
          description: >-
            Una voce per ciascun campo confrontato per il tipo di entità della
            parte (`name`, `date_of_birth`, `address`, `account`; un'azienda non
            ha `date_of_birth`).
          additionalProperties:
            type: object
            properties:
              result:
                type: string
                enum:
                  - matched
                  - mismatched
                  - not_compared
                description: >-
                  `not_compared` quando la regola è `NONE` o una delle due parti
                  non ha un valore per il campo.
              strictness:
                type: string
                enum:
                  - NONE
                  - STRICT
                  - CONTAINS
                  - DEFAULT
                  - FUZZY
    TravelRuleDataUnmasked:
      type: object
      nullable: true
      description: >-
        Registro di audit del momento in cui i dati della controparte sono stati
        smascherati. Null finché i dati sono ancora mascherati e per i
        trasferimenti in uscita.
      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: >-
            Cosa ha confermato l'assetto proprietario: ownership_confirmed (la
            tua conferma tramite la console o l'API), wallet_proof (una prova
            del wallet nel widget o un trasferimento in entrata INTERNAL,
            impostato al momento della creazione), address_book_match (un wallet
            verificato nella rubrica), own_verified_wallet (il wallet verificato
            del tuo utente), inquiry_approved (la tua approvazione di una
            richiesta TRP in entrata o di un messaggio GTR o Sygna),
            known_payment_method (un wallet con cui il tuo utente ha già pagato)
            o travel_address (il Travel Address associato al wallet ha
            denominato il wallet).
        actor:
          type: string
          description: >-
            Chi l'ha confermata: l'email dell'utente della console o l'etichetta
            della chiave API. Vuoto per una decisione automatica.
    TravelRuleDelivery:
      type: object
      description: >-
        Lo stato dell'ultimo messaggio dovuto dal trasferimento alla
        controparte. Didit contatta la controparte dopo la restituzione della
        richiesta che ha creato o modificato il trasferimento, quindi questo
        oggetto indica se tale messaggio è andato a buon fine: in coda, in fase
        di invio, in attesa di un nuovo tentativo dopo un errore, consegnato o
        non riuscito. In caso di errore da cui la rete può ancora riprendersi
        (nessuna risposta in tempo, connessione non riuscita, HTTP `408`, `429`
        o `5xx`), viene effettuato un nuovo tentativo dopo 30 secondi, 2 minuti,
        10 minuti, 30 minuti e 1 ora. Quando un primo messaggio (`kind: SEND`)
        fallisce definitivamente, perché la rete lo ha rifiutato o anche il
        sesto tentativo non è riuscito, il trasferimento passa a
        `COUNTERPARTY_VASP_NOT_REACHABLE` con `last_error` nella sua `timeline`;
        qualsiasi altro messaggio che fallisce definitivamente viene annotato
        nella `timeline`. Lo `status` del trasferimento rimane l'unica fonte di
        verità per lo scambio stesso.
      required:
        - kind
        - status
        - rail
        - attempts
        - last_error
        - next_attempt_at
        - delivered_at
      properties:
        kind:
          type: string
          enum:
            - SEND
            - ANSWER
            - TXID
            - CANCEL
            - POLL
          description: >-
            Cosa trasporta il messaggio. `SEND`: il primo messaggio del
            trasferimento verso la controparte (in uscita; il canale viene
            scelto al momento dell'invio). `ANSWER`: la tua accettazione o
            rifiuto, dovuta alla rete che ha effettuato la richiesta (in
            entrata). `TXID`: l'hash della transazione on-chain, dopo aver
            completato il trasferimento. `CANCEL`: l'annullamento, dopo averlo
            cancellato. `POLL`: una richiesta di stato verso una rete che la
            supporta, ripetuta ogni 5 minuti mentre il trasferimento è in attesa
            della controparte.
        status:
          type: string
          enum:
            - QUEUED
            - SENDING
            - RETRYING
            - DELIVERED
            - FAILED
          description: >-
            `QUEUED`: in attesa di invio. `SENDING`: tentativo in corso.
            `RETRYING`: un tentativo non è riuscito e il prossimo verrà eseguito
            alle `next_attempt_at`. `DELIVERED`: l'altra parte ha ricevuto il
            messaggio. `FAILED`: l'altra parte lo ha rifiutato o l'ultimo
            tentativo non è riuscito.
        rail:
          type: string
          enum:
            - INTERNAL
            - TRP
            - GTR
            - TRUST
            - VERIFYVASP
            - SYGNA
            - EMAIL
            - ''
          description: >-
            Il canale (rail) che trasporta il messaggio. Vuoto finché Didit non
            ne sceglie uno per un primo messaggio.
        attempts:
          type: integer
          minimum: 0
          description: >-
            Tentativi effettuati finora per questo messaggio. Per un messaggio
            che non è un polling di stato vengono effettuati al massimo 6
            tentativi.
        last_error:
          type: string
          description: >-
            Il tipo di errore riscontrato nell'ultimo tentativo, `""` se non ce
            ne sono stati: ad esempio `email undeliverable`, `trp identity
            endpoint unreachable` o `trp transfer inquiry delivery failed`. Non
            contiene mai la risposta della controparte stessa, che rimane nella
            `timeline` del trasferimento.

            Quando GTR risponde con un errore, vengono inclusi il codice di
            stato e il messaggio restituiti. I corpi della risposta non vengono
            mai inclusi.
          example: email undeliverable
        next_attempt_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Quando verrà eseguito il prossimo tentativo mentre il messaggio è in
            stato `QUEUED` o `RETRYING`.
        delivered_at:
          type: string
          format: date-time
          nullable: true
          description: Quando l'altra parte ha preso in carico il messaggio.
    TravelRuleDiscoveryStep:
      type: object
      description: >-
        Un passaggio del rilevamento della controparte eseguito da Didit per un
        trasferimento in uscita, nell'ordine in cui è stato eseguito. Il primo
        passaggio che identifica un VASP con un percorso conclude la catena.
      properties:
        step:
          type: string
          enum:
            - internal_address_book
            - wallet_attribution
            - network_lookup
            - customer_hint
            - end_user
          description: >-
            `internal_address_book`: un altro cliente Didit che ha dimostrato il
            controllo del wallet di destinazione. `wallet_attribution`:
            l'attribuzione di analisi blockchain del wallet. `network_lookup`:
            una rete in grado di indicare quale VASP detiene l'indirizzo.
            `customer_hint`: il nome del VASP, LEI o la giurisdizione che hai
            inviato in `beneficiary_data`. `end_user`: la controparte scelta
            dall'utente finale (o da te), oppure la richiesta di sceglierne una.
        outcome:
          type: string
          enum:
            - match
            - miss
            - skipped
          description: >-
            `match`: il passaggio ha indicato una controparte. `miss`: è stato
            eseguito e non ne ha trovata nessuna. `skipped`: non è stato
            possibile eseguirlo e `reason` ne indica il motivo.
        reason:
          type: string
          description: >-
            Motivo leggibile dalla macchina, `""` in caso di corrispondenza:
            `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` o `picked_member_without_proven_wallet`.
        vasp:
          type: string
          format: uuid
          nullable: true
          description: >-
            Il VASP della directory indicato dal passaggio, qualora ne abbia
            indicato uno.
        rail:
          type: string
          nullable: true
          description: >-
            Il canale (rail) che raggiunge tale controparte, quando il passaggio
            ne ha trovato uno.
        at:
          type: string
          format: date-time
    TravelRuleNextAction:
      type: object
      description: >-
        Un elemento che consente di far progredire un trasferimento bloccato
        nello stato `COUNTERPARTY_VASP_NOT_FOUND` o
        `COUNTERPARTY_VASP_NOT_REACHABLE`. Consulta [Perché un trasferimento è
        bloccato](/it/transaction-monitoring/travel-rule#perché-un-trasferimento-è-bloccato).
      properties:
        action:
          type: string
          enum:
            - select_counterparty_vasp
            - declare_self_hosted
            - add_vasp_hint
            - update_compliance_email
            - resend
          description: >-
            `select_counterparty_vasp`: l'utente finale seleziona il VASP di
            destinazione nel widget di titolarità del wallet, oppure invii una
            richiesta PATCH con `action=beneficiary_vasp`.
            `declare_self_hosted`: l'utente finale dichiara che il wallet è in
            autocustodia nel widget. `add_vasp_hint`: indica a Didit chi è la
            controparte specificando nome del VASP, LEI o Travel Address (ad
            esempio un `travel_address` nella voce della rubrica del wallet di
            destinazione), quindi invia nuovamente. `update_compliance_email` e
            `resend` sono valori di `action` per `PATCH
            /v3/transactions/{transaction_id}/travel-rule/`: fornisci nuovamente
            l'email di compliance della controparte ed esegui nuovamente
            l'instradamento.
        url:
          type: string
          format: uri
          description: >-
            Il link al widget di verifica della proprietà del wallet, su
            `select_counterparty_vasp` e `declare_self_hosted` mentre il
            trasferimento ha una sessione widget aperta.
      required:
        - action
    TravelRuleChainDetails:
      type: object
      description: >-
        In che modo la blockchain del trasferimento identifica i suoi due
        wallet, quando si tratta di più di un indirizzo che ne paga un altro.
        Vuoto (`{}`) per un trasferimento su blockchain basata su account (EVM,
        Solana, Tron), dove i due indirizzi corrispondono ai wallet. La
        corrispondenza, l'instradamento e la rubrica leggono innanzitutto i
        wallet da qui.
      properties:
        chain:
          type: string
          description: >-
            Rete blockchain canonica, ad es. `BTC`, `XRP` o `LIGHTNING` per un
            trasferimento Lightning.
        shape:
          type: string
          enum:
            - utxo
            - memo
            - lightning
        originator:
          $ref: '#/components/schemas/TravelRuleChainSide'
        beneficiary:
          $ref: '#/components/schemas/TravelRuleChainSide'
        utxo:
          type: object
          description: >-
            Su un trasferimento UTXO: gli input e gli output come memorizzati
            (importi come stringhe decimali) e quali output Didit ha
            interpretato come cosa.
          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: Output che rimborsano un indirizzo di input.
            beneficiary_output_index:
              type: integer
              nullable: true
              description: >-
                L'output che paga il beneficiario; null quando non è stato
                possibile distinguerne alcuno.
        lightning:
          type: object
          description: >-
            Su un trasferimento Lightning: ciò che indica la richiesta di
            pagamento. Sempre `kind` (`bolt11`, `bolt12_offer`,
            `bolt12_invoice`, `bolt12_invoice_request`, `lnurl`,
            `lightning_address`, `node_id` o `unknown`); una fattura BOLT11
            aggiunge `network`, `payee_node_id`, `payment_hash`, `amount_msat`,
            `created_at` e `expires_at`; una stringa BOLT12 `blinded_paths` e
            `payee_node_id`; un LNURL o un Lightning Address il suo `domain`.
            Nulla viene risolto sulla rete: la richiesta viene solo
            decodificata.
          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: >-
            Incongruenze UTXO da esaminare: l'ordinante dichiarato non è un
            input, il beneficiario dichiarato non è un output, non è stato
            possibile distinguere un singolo output del beneficiario, oppure
            l'output del beneficiario corrisponde a un importo diverso rispetto
            a quello indicato nella transazione.
        not_applicable_reason:
          type: string
          enum:
            - LIGHTNING_NO_PAYEE_IDENTIFIER
            - LIGHTNING_BOLT12_BLINDED_PAYEE
            - LIGHTNING_LNURL_NAMES_NO_PAYEE
          description: >-
            Su un trasferimento Lightning in uscita la cui richiesta di
            pagamento non indica alcun beneficiario: perché il trasferimento è
            `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (la richiesta non
            indica alcun nodo beneficiario o non è stato possibile
            decodificarla), `LIGHTNING_BOLT12_BLINDED_PAYEE` (l'offerta nasconde
            il proprio beneficiario dietro percorsi ciechi),
            `LIGHTNING_LNURL_NAMES_NO_PAYEE` (un LNURL indica un servizio, non
            un beneficiario). Lo stesso codice apre l'ultima voce `timeline` del
            trasferimento.
    TravelRuleChainSide:
      type: object
      description: >-
        Il wallet di una delle parti, così come Didit lo ha risolto a partire
        dai dati della blockchain.
      properties:
        address:
          type: string
          description: >-
            Il wallet. Su una rete con memo l'indirizzo classico (un X-address
            XRP viene suddiviso nel relativo indirizzo classico e tag); su
            Lightning l'ID del nodo del beneficiario o il Lightning Address.
        memo:
          type: string
          description: Il destination tag o memo che fa parte del wallet; `""` se assente.
        source:
          type: string
          enum:
            - declared
            - x_address
            - largest_input
            - only_non_change_output
            - amount_match
            - invoice_payee
            - updated
          description: >-
            Origine del wallet: `declared` (la tua richiesta), `x_address`
            (estratto da un X-address XRP), `largest_input` (l'indirizzo di
            input UTXO che ha contribuito maggiormente),
            `only_non_change_output` (l'unico output UTXO non di resto),
            `amount_match` (l'unico output UTXO che paga l'importo del
            trasferimento), `invoice_payee` (il beneficiario indicato in una
            richiesta di pagamento Lightning), `updated` (impostato
            successivamente con `action: update_originator_wallet`).
    TravelRuleUtxoEntry:
      type: object
      description: >-
        Un input o output di una transazione UTXO, così come registrato dalla
        blockchain.
      required:
        - address
      properties:
        address:
          type: string
          maxLength: 128
        amount:
          type: string
          nullable: true
          description: >-
            Stringa decimale nell'unità propria della moneta (BTC, non satoshi).
            Facoltativo.
          example: '0.0125'
        txid:
          type: string
          maxLength: 128
          description: Opzionale. La transazione utilizzata da un input.
        vout:
          type: integer
          nullable: true
          minimum: 0
          description: Opzionale. L'indice di output speso da un input.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La chiave API della tua applicazione, da Developers -> API keys nella
        Business Console. La chiave primaria ha accesso completo. Una chiave con
        nome può avere un ambito definito: nessuno, lettura o scrittura per
        risorsa, limitata ad alcuni workflow o a sessioni approvate, a un elenco
        di indirizzi IP e a una data di scadenza. 401 indica che la chiave è
        errata, revocata o scaduta; 403 indica che non è stata inviata alcuna
        chiave, che la chiave non ha accesso a questa risorsa o azione, oppure
        che la richiesta proviene da un indirizzo non incluso nel suo elenco IP;
        404 su una route di sessione indica che la sessione non rientra nei
        workflow o negli stati previsti dalla chiave. Una chiave senza accesso
        ai media riceve gli URL di immagini, video e PDF come null, e una chiave
        senza permessi di scrittura sulle sessioni riceve link e token di
        sessione come null. Consulta https://docs.didit.me/console/api-keys.

````

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