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

# Регистрация входящего перевода Sunrise: API Travel Rule

> Регистрация данных Travel Rule для криптодепозита, уже зачисленного в блокчейне до обмена. Поток Sunrise после зачисления средств в Didit.



Промпт для API регистрации входящего перевода Sunrise
        Скопировать промпт в буфер обмена



      
      

\<pre>

\`Register Travel Rule data for a crypto deposit that settled on-chain BEFORE any exchange took place - because the sending VASP was unreachable at the time (the sunrise problem), or when backfilling historical deposits.

Endpoint:
POST https://verification.didit.me/v3/travel-rule/inbound/

Authentication:
Use the x-api-key header with my Didit API key. You are the beneficiary VASP.

Request body (application/json):
\{
"chain": "ETH",                        // required; stored lowercased and matched case-insensitively against your address-book entries' chain
"txid": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",   // dedupe key: same txid + wallet_address returns the existing transfer
"wallet_address": "0x8ba1f109551bD432803012645Ac136ddd64DBA72",   // an XRP X-address is split into its classic address and tag
"memo": "",                              // optional destination tag or memo: on a shared deposit address it names your customer
"amount": "500.00",
"currency": "USDC",
"originator_data": { "name": "Origin CASP SL" },      // flat originator details from the sender, if known (name or full_name, first_name, last_name, vendor_data)
"beneficiary_data": { "name": "Ana Diaz" },           // flat beneficiary details (your customer); name is matched against the entry's holder_name
"originating_vasp": { "name": "Origin CASP SL", "lei": "984500ABCDEF12345634", "travel_address": "taHg7hkTmJ4mTpdQxn61H9cyx6RreB2jrDHeB3pkioRRBgKQaSAGUzp73FVsmEXXJVxdAuCCWiBEFMkcB4MCtcyjnpbyEbTeSHwym394NMS7ev" },  // optional sender identity
"utxo": { "inputs": [ { "address": "bc1q...", "amount": "0.5" } ], "outputs": [ { "address": "bc1q...", "amount": "0.25" } ] }  // optional, BTC/LTC/BCH/DOGE only
}

Behavior:
\- Creates an inbound travelRule transaction (or reuses an unclaimed recorded deposit) and resolves it against your wallet address book, by the address and its memo (an entry with exactly that memo first, else one for the whole address; a deposit without a memo never reaches an entry that has one):
\- no matching entry -> ON_HOLD
\- entry exists, ownership unproven -> UNCONFIRMED_OWNERSHIP
\- name does not match the entry's holder_name -> COUNTERPARTY_MISMATCHED_DATA
\- verified entry + name match -> COMPLETED then immediately FINISHED (the deposit already settled).
\- The address-book match is chain-scoped: an entry matches when its chain equals the request chain (case-insensitive) or the entry's chain is blank, and "ethereum" does not match "ETH".
\- Resolve ON_HOLD (and UNCONFIRMED_OWNERSHIP) with POST /v3/transactions/{transaction_id}/travel-rule/ownership/.
\{"confirmed": true} registers or verifies the wallet entry and runs the name match; {"confirmed": false} declines the transfer.
ON_HOLD does not change the transaction status by itself; only a rule that acts on the Travel Rule status changes it (for example the opt-in library preset travel-rule-pending-action sets AWAITING_USER).
\- Naming originating_vasp keeps the sender's identity on this transfer (metadata.originating_vasp, and the transfer's originator VASP in GET /v3/travel-rule/transfers/); it never creates or changes a shared VASP directory entry.
originating_vasp.lei must be a valid 20-character LEI (ISO 17442) or blank, and originating_vasp.travel_address must be a valid travel address or blank.
An inbound TRP inquiry does not create or change its sender's directory entry either.
\- Webhooks: when a new transaction was created, transaction.created is sent first and travel_rule.status.updated follows for each status transition.
Each webhook is delivered and retried on its own, so do not rely on arrival order; key on transaction_id.
\- Billing: there is no base fee.
A newly created deposit is screened and charged the Wallet Verification & Screening rate only when crypto monitoring is enabled and chain is one Didit can screen (btc, eth, sol, trx, matic, bnb, ltc, xrp, bch, doge, or their full names such as bitcoin or ethereum).
Sandbox applications are never charged.
\- utxo: the sender's wallet is originator_data.wallet_address when you declare it, else the input address that contributed the most. The result is on travel_rule.chain_details.

What to read from the response:
\- transaction_id - the Didit transaction uuid, used in /v3/transactions/{transaction_id}/ calls.
\- txn_id - tr-in-{first 80 characters of txid}-{12 hex characters} for a new transaction, or the existing txn_id of a reused recorded deposit.
\- created - true (201) when this call registered the deposit, false (200) when the same txid + wallet_address was already registered.
\- travel_rule - the full transfer object: uuid, status, direction, rail, protocol, ivms_version, required, ownership_confirmed, deadline_at, timeline, counterparty_vasp, originator_data, beneficiary_data, delivery, discovery, reason, next_actions, created_at.
beneficiary_data includes the wallet_address and the lowercased chain.
originator_data and beneficiary_data stay masked in the response (data_masked: true) until wallet ownership is confirmed.
\- travel_rule.status - the resolved state (see above).

Failure modes:
\- 400 - a missing required field (chain, txid, wallet_address, amount, currency), an invalid originating_vasp.lei, or an invalid travel address ("Invalid travel address.").
\- 403 - missing x-api-key (a wrong, revoked or expired key gets 401).

Full guide: /transaction-monitoring/travel-rule#after-deposit-sunrise-registration.`

\</pre>



      
      

Вставьте в



## OpenAPI

````yaml ru/openapi-25.json POST /v3/travel-rule/inbound/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: >-
    API верификации личности. Аутентификация выполняется с помощью заголовка
    x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/travel-rule/inbound/:
    post:
      tags:
        - Travel Rule
      summary: Зарегистрировать входящий перевод после депозита (sunrise)
      description: >-
        Зарегистрировать данные Travel Rule для криптовалютного депозита,
        который уже был проведён ончейн до совершения какого-либо обмена.
        Создаёт входящую транзакцию travelRule (или повторно использует
        невостребованный депозит) и сопоставляет перевод с вашей адресной книгой
        кошельков. Для вновь созданной транзакции Didit сначала отправляет
        webhook transaction.created, а затем webhook travel_rule.status.updated.
      operationId: registerTravelRuleInbound
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TravelRuleInboundRequest'
            example:
              chain: ETH
              txid: 0xdeposit-hash
              wallet_address: 0xYourDepositWallet
              amount: '500.00'
              currency: USDC
              originator_data:
                name: Origin CASP SL
              beneficiary_data:
                name: Ana Diaz
              originating_vasp:
                name: Origin CASP SL
                lei: ''
                travel_address: >-
                  ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC
      responses:
        '200':
          description: >-
            Перевод для этого txid и wallet_address уже был зарегистрирован;
            существующий перевод возвращён без изменений (created равно false).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelRuleInboundResponse'
        '201':
          description: >-
            Новый перевод Travel Rule был зарегистрирован для новой входящей
            транзакции или существующего невостребованного депозита (created
            равно true).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelRuleInboundResponse'
        '400':
          description: >-
            Обязательное поле (`chain`, `txid`, `wallet_address`, `amount`,
            `currency`) отсутствует, `originating_vasp.lei` не является
            корректным LEI, `originating_vasp.travel_address` не является
            корректным Travel Address, указан memo, X-address или `utxo`,
            который сеть не поддерживает, либо `originator_data` /
            `beneficiary_data` не является объектом.
          content:
            application/json:
              examples:
                Missing field:
                  value:
                    txid:
                      - This field is required.
                Invalid LEI:
                  value:
                    originating_vasp:
                      lei:
                        - >-
                          Invalid LEI: expected 20 alphanumeric characters (ISO
                          17442).
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/travel-rule/inbound/ \
              -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \
              -d '{"chain":"ETH","txid":"0xdeposit-hash","wallet_address":"0xYourDepositWallet","amount":"500.00","currency":"USDC"}'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.travel_rule.register_inbound(
                chain="ETH",
                txid="0xdeposit-hash",
                wallet_address="0xYourDepositWallet",
                amount="500.00",
                currency="USDC",
                originator_data={"name": "Origin CASP SL"},
                beneficiary_data={"name": "Ana Diaz"},
                originating_vasp={
                    "name": "Origin CASP SL",
                    "lei": "",
                    "travel_address": "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC",
                },
            )
            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.travelRule.registerInbound({
              chain: "ETH",
              txid: "0xdeposit-hash",
              wallet_address: "0xYourDepositWallet",
              amount: "500.00",
              currency: "USDC",
              originator_data: { name: "Origin CASP SL" },
              beneficiary_data: { name: "Ana Diaz" },
              originating_vasp: {
                name: "Origin CASP SL",
                lei: "",
                travel_address: "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC",
              },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RegisterInbound(ctx, didit.TravelRuleInboundRequest{\n\tChain:           \"ETH\",\n\tTxid:            \"0xdeposit-hash\",\n\tWalletAddress:   \"0xYourDepositWallet\",\n\tAmount:          \"500.00\",\n\tCurrency:        \"USDC\",\n\tOriginatorData:  didit.Some(map[string]any{\"name\": \"Origin CASP SL\"}),\n\tBeneficiaryData: didit.Some(map[string]any{\"name\": \"Ana Diaz\"}),\n\tOriginatingVASP: didit.Some(didit.TravelRuleInboundRequestOriginatingVASP{\n\t\tName:          didit.String(\"Origin CASP SL\"),\n\t\tLei:           didit.String(\"\"),\n\t\tTravelAddress: didit.String(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.TravelRuleInboundRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.travelRule().registerInbound(TravelRuleInboundRequest.builder()
                    .chain("ETH")
                    .txid("0xdeposit-hash")
                    .walletAddress("0xYourDepositWallet")
                    .amount("500.00")
                    .currency("USDC")
                    .originatorData(Map.of("name", "Origin CASP SL"))
                    .beneficiaryData(Map.of("name", "Ana Diaz"))
                    .originatingVasp(TravelRuleInboundRequest.OriginatingVasp.builder()
                            .name("Origin CASP SL")
                            .lei("")
                            .travelAddress("ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC")
                            .build())
                    .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->travelRule->registerInbound([
                'chain' => 'ETH',
                'txid' => '0xdeposit-hash',
                'wallet_address' => '0xYourDepositWallet',
                'amount' => '500.00',
                'currency' => 'USDC',
                'originator_data' => ['name' => 'Origin CASP SL'],
                'beneficiary_data' => ['name' => 'Ana Diaz'],
                'originating_vasp' => [
                    'name' => 'Origin CASP SL',
                    'lei' => '',
                    'travel_address' => 'ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC',
                ],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.travel_rule.register_inbound(
              chain: "ETH",
              txid: "0xdeposit-hash",
              wallet_address: "0xYourDepositWallet",
              amount: "500.00",
              currency: "USDC",
              originator_data: { name: "Origin CASP SL" },
              beneficiary_data: { name: "Ana Diaz" },
              originating_vasp: {
                name: "Origin CASP SL",
                lei: "",
                travel_address: "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC",
              }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.TravelRule.RegisterInboundAsync(new
            TravelRuleInboundRequest

            {
                Chain = "ETH",
                Txid = "0xdeposit-hash",
                WalletAddress = "0xYourDepositWallet",
                Amount = "500.00",
                Currency = "USDC",
                OriginatorData = new Dictionary<string, object> { ["name"] = "Origin CASP SL" },
                BeneficiaryData = new Dictionary<string, object> { ["name"] = "Ana Diaz" },
                OriginatingVasp = new TravelRuleInboundRequestOriginatingVasp
                {
                    Name = "Origin CASP SL",
                    Lei = "",
                    TravelAddress = "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC",
                },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    TravelRuleInboundRequest:
      type: object
      required:
        - chain
        - txid
        - wallet_address
        - amount
        - currency
      properties:
        chain:
          type: string
          description: >-
            Блокчейн, в котором был обработан депозит, например `ETH`.
            Сохраняется в нижнем регистре и сравнивается без учёта регистра с
            записями в адресной книге ваших кошельков, поэтому используйте там
            тот же token блокчейна.
          maxLength: 32
        txid:
          type: string
          description: Ончейн-хеш транзакции. Дедуплицируется вместе с wallet_address.
          maxLength: 128
        wallet_address:
          type: string
          description: >-
            Кошелёк назначения, на который вы получили депозит. XRP X-address
            разделяется на классический адрес и тег.
          maxLength: 128
        amount:
          type: string
          description: >-
            Сумма депозита в виде десятичной строки, ноль или больше, до 18
            знаков после запятой.
        currency:
          type: string
          description: Актив депозита, например, "USDC".
          maxLength: 16
        originator_data:
          type: object
          description: >-
            Данные об отправителе от отправляющего VASP, если они известны, в
            виде плоского объекта, такого как `{"name": "..."}`. Didit считывает
            из него name (или full_name), first_name, last_name и vendor_data.
          additionalProperties: true
        beneficiary_data:
          type: object
          description: >-
            Данные получателя (вашего клиента) в виде плоского объекта, например
            `{"name": "..."}`. Didit сопоставляет имя с holder_name
            соответствующей записи адресной книги и устанавливает wallet_address
            и chain из запроса.
          additionalProperties: true
        originating_vasp:
          type: object
          description: >-
            Необязательное описание отправляющего VASP. Оно остаётся только в
            этом переводе (`metadata.originating_vasp` и VASP отправителя
            перевода в GET /v3/travel-rule/transfers/); оно никогда не создаёт,
            не редактирует и не связывает общую запись в справочнике VASP.
          properties:
            name:
              type: string
              maxLength: 255
            lei:
              type: string
              maxLength: 20
              description: >-
                Необязательно. Действительный 20-значный LEI по стандарту ISO
                17442 или пустое значение.
            travel_address:
              type: string
              description: Travel Address отправителя, зафиксированный для этого перевода.
              maxLength: 512
        memo:
          type: string
          maxLength: 256
          description: >-
            Необязательно. Тег назначения (destination tag) или memo депозита в
            сети с поддержкой memo: на общем адресе депозита он позволяет
            различать ваших клиентов, и запись в адресной книге для этого memo
            сопоставляется. XRP: destination tag, целое число от 0 до 4294967295
            (принимается число JSON). XLM: текстовое memo длиной до 28 байт,
            64-битный идентификатор или 32-байтный хэш в шестнадцатеричном
            формате. EOS: до 256 байт. ATOM: до 256 символов. HBAR: до 100 байт.
            Кошельки Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash,
            Dogecoin и Lightning не принимают memo: его наличие возвращает
            `400`. Псевдоним: `destinationTag` или `destination_tag`.
        utxo:
          allOf:
            - $ref: '#/components/schemas/TravelRuleUtxo'
          description: >-
            Необязательно, только для сетей UTXO. Входы и выходы транзакции
            депозита: кошельком отправителя является объявленный
            `originator_data.wallet_address`, иначе наибольший вход.
    TravelRuleInboundResponse:
      type: object
      properties:
        transaction_id:
          type: string
          format: uuid
          description: UUID транзакции Didit для входящего депозита.
        txn_id:
          type: string
          description: >-
            txn_id входящей транзакции: сгенерированный Didit, если транзакцию
            создала Didit, или ваш собственный, если был повторно использован
            невостребованный депозит.
        created:
          type: boolean
          description: >-
            true, если этот вызов зарегистрировал перевод (HTTP 201); false,
            если перевод с теми же txid и wallet_address уже существовал (HTTP
            200).
        travel_rule:
          $ref: '#/components/schemas/TravelRuleTransferDetail'
    TravelRuleUtxo:
      type: object
      description: >-
        Входы и выходы UTXO-перевода (BTC, LTC, BCH, DOGE). Принимаются только
        для этих сетей: для любой другой сети возвращается `400`. На их основе
        Didit определяет кошелёк отправителя (заявленный, иначе входной адрес с
        наибольшим вкладом) и выход получателя (заявленный, иначе единственный
        выход, который не возвращает сдачу на входной адрес, иначе выход,
        выплачивающий сумму перевода). Результат находится в `chain_details`
        перевода.
      required:
        - outputs
      properties:
        inputs:
          type: array
          maxItems: 1000
          items:
            $ref: '#/components/schemas/TravelRuleUtxoEntry'
          description: >-
            Необязательно. Без входов (inputs) отправитель не определяется, а
            выход со сдачей (change output) не распознается.
        outputs:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            $ref: '#/components/schemas/TravelRuleUtxoEntry'
    TravelRuleTransferDetail:
      type: object
      description: >-
        Полный объект перевода, возвращаемый endpoint’ами подтверждения владения
        и завершения/отмены. Пока владение кошельком для входящего перевода не
        подтверждено, данные контрагента `originator_data` и `beneficiary_data`
        возвращаются маскированными (сохраняется первая буква каждого слова;
        кошелёк, сеть и маршрутизация VASP остаются читаемыми), а флаг
        `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: >-
            Транспортная сеть (rail), через которую был направлен перевод, или
            null, если сеть не была выбрана (например, ниже порога,
            некастодиальный кошелёк контрагента, регистрация после депозита или
            отсутствие доступного контрагента). INTERNAL означает, что обе
            стороны являются приложениями Didit; EMAIL означает, что контрагент
            получил ссылку для получения по электронной почте. TEST_VASP
            означает, что Didit Test VASP ответил на перевод в песочнице. В
            сетях GTR, VERIFYVASP и SYGNA Didit считывает ответ контрагента из
            ответа сети или опрашивает её каждые 5 минут. TRUST работает только
            на отправку, поэтому перевод через TRUST остаётся в статусе
            AWAITING_COUNTERPARTY до истечения срока действия. Сетевой rail
            используется только тогда, когда вы подключили собственное участие
            (membership) для этой сети. Он выбирается после возврата ответа
            создания транзакции, поэтому в этом ответе он равен null.
        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: >-
                  Сравнение имён, на основании которого принято решение в этой
                  записи, рядом с `detail`. Отсутствует в записях, где сравнение
                  имени не проводилось.
              reason:
                type: string
                description: >-
                  Присутствует только в записи о переходе, вызванном неудачной
                  доставкой: `email_undeliverable` или `delivery_failed`,
                  значение, которое возвращает поле `reason` перевода.
        counterparty_vasp:
          type: object
          nullable: true
          properties:
            name:
              type: string
            lei:
              type: string
            dd_score:
              type: integer
              description: >-
                Оценка дью-дилидженс от 0 до 100, где большее значение лучше. Та
                же шкала, что и в каталоге VASP.
            dd_score_breakdown:
              type: object
              description: >-
                Вклад каждого компонента в dd_score: один объект на компонент в
                соответствии со справочником VASP (jurisdiction, verification,
                protocol, lei, history, essentials, responsiveness), каждый со
                структурой {points, max, reason, detail}. Пустой объект {}, пока
                контрагент не был оценён.
              additionalProperties:
                type: object
                properties:
                  points:
                    type: number
                    description: Баллы, начисленные за этот компонент.
                  max:
                    type: integer
                    description: >-
                      Максимальное количество баллов, которое может начислить
                      этот компонент.
                  reason:
                    type: string
                    description: Машиночитаемый код вердикта компонента.
                  detail:
                    type: string
                    description: Понятная человеку причина начисления баллов.
            dd_assessed_at:
              type: string
              format: date-time
              nullable: true
              description: >-
                Когда в последний раз проводилась оценка в рамках комплексной
                проверки. Null, пока контрагент не был оценён.
        originator_data:
          type: object
          description: >-
            Сторона-отправитель. Для входящего перевода значения контрагента
            маскируются до тех пор, пока владение не будет подтверждено.
        beneficiary_data:
          type: object
          description: >-
            Сторона-получатель. Для входящего перевода значения контрагента
            маскируются до подтверждения владения.
        name_match:
          allOf:
            - $ref: '#/components/schemas/TravelRuleNameMatch'
          nullable: true
          description: >-
            Сравнение имен, на основе которого было принято решение по переводу,
            или null до выполнения проверки. Пока стороны маскированы, а также в
            копии транзакции INTERNAL у другого клиента, поля `transfer_name`,
            `compared_name`, `matched_names` и `mismatched_names` скрыты.
            Значения `score` и `matched` могут расходиться: `matched` следует
            уровню строгости, а `score` отражает степень сходства двух полных
            имен.
        data_match:
          $ref: '#/components/schemas/TravelRuleDataMatch'
        mismatched_fields:
          type: array
          items:
            type: string
          description: >-
            Сокращение для `data_match.mismatched_fields`. Пусто, если различий
            нет.
        data_unmasked:
          $ref: '#/components/schemas/TravelRuleDataUnmasked'
        data_masked:
          type: boolean
          description: >-
            Имеет значение true, пока персональные данные контрагента
            маскируются в этом ответе.
        created_at:
          type: string
          format: date-time
        delivery:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TravelRuleDelivery'
          description: >-
            Текущий статус последнего сообщения, которое этот перевод должен
            отправить другой стороне. Null, если перевод не требовал отправки
            сообщения (например, ниже `threshold_amount`, заявленный
            некастодиальный кошелёк или регистрация в рамках sunrise-периода).
        discovery:
          type: array
          description: >-
            Как Didit выполнял поиск контрагента: по одной записи на каждый
            выполненный шаг. Пусто, если поиск не выполнялся, например для
            входящего перевода.
          items:
            $ref: '#/components/schemas/TravelRuleDiscoveryStep'
        reason:
          type: string
          description: >-
            Причина, по которой перевод со статусом
            `COUNTERPARTY_VASP_NOT_FOUND` или `COUNTERPARTY_VASP_NOT_REACHABLE`
            приостановлен; `""` для любого другого статуса. Неудачная доставка
            определяет её в первую очередь и только при
            `COUNTERPARTY_VASP_NOT_REACHABLE`: `email_undeliverable` (почтовый
            провайдер отклонил комплаенс-письмо, и адресов для повторной попытки
            не осталось: при отправке, при напоминании или в виде постоянного
            сбоя доставки, о котором сообщено позже) или `delivery_failed`
            (канал доставки окончательно вышел из строя: сетевой канал отклонил
            сообщение или исчерпал лимит повторных попыток, хост идентификации
            `TRP` не ответил либо `TRP`-хост контрагента не принял запрос). В
            противном случае её определяет трассировка `discovery`:
            `awaiting_end_user` (ни на одном шаге не указан контрагент, с
            которым Didit может связаться), `directory_match_no_route` (на шаге
            указан VASP из каталога, у которого нет маршрута),
            `picked_member_without_proven_wallet` (конечный пользователь выбрал
            клиента Didit, который не подтвердил контроль над кошельком) или
            `no_directory_match`, если трассировка не возвращает иной причины.
            Повторная отправка продвигает перевод дальше, поэтому причина
            сбрасывается. См. [Почему перевод
            приостановлен](/ru/transaction-monitoring/travel-rule#почему-перевод-застрял).
        next_actions:
          type: array
          description: >-
            Действия, продвигающие перевод дальше; `[]` для любого статуса,
            кроме `COUNTERPARTY_VASP_NOT_FOUND` или
            `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` предлагает
            `update_compliance_email`, затем `resend`. `delivery_failed`
            предлагает `resend`. Причина типа discovery предлагает
            `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint` и
            `resend`.
          items:
            $ref: '#/components/schemas/TravelRuleNextAction'
        chain_details:
          $ref: '#/components/schemas/TravelRuleChainDetails'
    TravelRuleUtxoEntry:
      type: object
      description: >-
        Один вход или выход UTXO-транзакции в том виде, в каком он зафиксирован
        в блокчейне.
      required:
        - address
      properties:
        address:
          type: string
          maxLength: 128
        amount:
          type: string
          nullable: true
          description: >-
            Десятичная строка в единицах самой монеты (BTC, не сатоши).
            Необязательно.
          example: '0.0125'
        txid:
          type: string
          maxLength: 128
          description: Необязательно. Транзакция, которую расходует вход (input).
        vout:
          type: integer
          nullable: true
          minimum: 0
          description: >-
            Необязательно. Индекс выхода (output index), который расходуется
            входом (input).
    TravelRuleNameMatch:
      type: object
      nullable: true
      description: >-
        Сравнение имен, на основе которого было принято решение по переводу, или
        null до выполнения проверки. Пока стороны маскированы, а также в копии
        транзакции INTERNAL у другого клиента, поля `transfer_name`,
        `compared_name`, `matched_names` и `mismatched_names` скрыты. Значения
        `score` и `matched` могут расходиться: `matched` следует уровню
        строгости, а `score` отражает степень сходства двух полных имен.
      properties:
        score:
          type: integer
          minimum: 0
          maximum: 100
          description: >-
            Степень сходства двух полных имен, от 0 до 100. Равно 0, если хотя
            бы одно имя пустое.
        matched:
          type: boolean
          description: >-
            Соответствуют ли имена значению `strictness`. Исход перевода зависит
            от `data_match`, где сравнивается каждое поле, поэтому перевод может
            иметь статус COUNTERPARTY_MISMATCHED_DATA, даже если здесь true.
        method:
          type: string
          enum:
            - none
            - exact_token
            - token_subset
            - token_containment
            - sequence_ratio
          description: >-
            Как определялось `matched`: none (`NONE`), exact_token (`STRICT`),
            token_subset (`DEFAULT`), token_containment (`CONTAINS`) или
            sequence_ratio (`FUZZY`).
        strictness:
          type: string
          enum:
            - NONE
            - STRICT
            - CONTAINS
            - DEFAULT
            - FUZZY
        compared_with:
          type: string
          enum:
            - wallet_holder
            - counterparty_vasp
          description: >-
            wallet_holder: владелец, указанный для кошелька. counterparty_vasp:
            название, указанное контрагентом на странице ответа по электронной
            почте, или ответ Didit Test VASP в песочнице.
        transfer_name:
          type: string
          description: Имя в переводе.
        compared_name:
          type: string
          description: Имя, с которым проводилось сравнение.
        matched_names:
          type: array
          items:
            type: string
          description: Слова из `transfer_name`, найденные в `compared_name`.
        mismatched_names:
          type: array
          items:
            type: string
          description: >-
            Слова из `transfer_name`, отсутствующие в `compared_name`, затем
            слова из `compared_name`, отсутствующие в `transfer_name`.
    TravelRuleDataMatch:
      type: object
      nullable: true
      description: >-
        Сравнение по каждому полю данных стороны перевода с тем, что известно
        другой стороне о владельце кошелька. Указывает поля и результаты, но
        никогда значения, сохраняя читаемость при маскировании данных
        контрагента. Имеет значение null до запуска сравнения.
      properties:
        matched:
          type: boolean
          description: True, когда ни одно из сравниваемых полей не отличается.
        mismatched_fields:
          type: array
          items:
            type: string
            enum:
              - name
              - date_of_birth
              - address
              - account
          description: Поля, которые различаются.
        fields:
          type: object
          description: >-
            Одна запись на каждое сравниваемое поле для типа стороны (`name`,
            `date_of_birth`, `address`, `account`; у компании нет поля
            `date_of_birth`).
          additionalProperties:
            type: object
            properties:
              result:
                type: string
                enum:
                  - matched
                  - mismatched
                  - not_compared
                description: >-
                  `not_compared`, если правило имеет значение `NONE` или на
                  одной из сторон отсутствует значение для поля.
              strictness:
                type: string
                enum:
                  - NONE
                  - STRICT
                  - CONTAINS
                  - DEFAULT
                  - FUZZY
    TravelRuleDataUnmasked:
      type: object
      nullable: true
      description: >-
        Запись аудита момента, когда данные контрагента были демаскированы.
        Имеет значение null, пока данные всё ещё замаскированы, а также для
        исходящих переводов.
      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: >-
            Что подтвердило владение: ownership_confirmed (ваше подтверждение
            через консоль или API), wallet_proof (подтверждение кошелька в
            виджете или входящий перевод INTERNAL, устанавливается при его
            создании), address_book_match (верифицированный кошелёк из адресной
            книги), own_verified_wallet (собственный верифицированный кошелёк
            вашего пользователя), inquiry_approved (ваше одобрение входящего
            TRP-запроса или сообщения GTR либо Sygna), known_payment_method
            (кошелёк, с которого ваш пользователь уже совершал оплату) или
            travel_address (Travel Address конкретного кошелька, обозначающий
            этот кошелёк).
        actor:
          type: string
          description: >-
            Кто подтвердил решение: email пользователя консоли или метка
            API-ключа. Пусто для автоматического решения.
    TravelRuleDelivery:
      type: object
      description: >-
        Текущий статус последнего сообщения, которое перевод должен отправить
        другой стороне. Didit связывается с контрагентом после возврата ответа
        на запрос, создавший или изменивший перевод, поэтому данный объект
        показывает, было ли доставлено это сообщение: в очереди, отправляется,
        ожидает повторной попытки после ошибки, доставлено или произошел сбой. В
        случае сбоя, после которого сеть еще может восстановиться (нет ответа
        вовремя, ошибка соединения, HTTP `408`, `429` или `5xx`), повторная
        попытка выполняется через 30 секунд, 2 минуты, 10 минут, 30 минут и 1
        час. Если первое сообщение (`kind: SEND`) окончательно завершается сбоем
        из-за отказа сети или неудачи шестой попытки, перевод переходит в статус
        `COUNTERPARTY_VASP_NOT_REACHABLE` с полем `last_error` в истории
        `timeline`; любое другое сообщение, окончательно завершившееся ошибкой,
        фиксируется в `timeline`. Поле `status` перевода остается
        первоисточником истины для самого обмена.
      required:
        - kind
        - status
        - rail
        - attempts
        - last_error
        - next_attempt_at
        - delivered_at
      properties:
        kind:
          type: string
          enum:
            - SEND
            - ANSWER
            - TXID
            - CANCEL
            - POLL
          description: >-
            Что содержит сообщение. `SEND`: первое сообщение перевода
            контрагенту (исходящее; канал передачи выбирается при отправке).
            `ANSWER`: ваше согласие или отклонение, направляемое запросившей
            сети (входящее). `TXID`: хеш ончейн-транзакции после завершения
            перевода. `CANCEL`: отмена после того, как вы отменили перевод.
            `POLL`: запрос статуса к сети, поддерживающей такую возможность,
            повторяемый каждые 5 минут, пока перевод ожидает ответа от
            контрагента.
        status:
          type: string
          enum:
            - QUEUED
            - SENDING
            - RETRYING
            - DELIVERED
            - FAILED
          description: >-
            `QUEUED`: ожидает отправки. `SENDING`: выполняется попытка.
            `RETRYING`: попытка завершилась неудачей, следующая запустится в
            `next_attempt_at`. `DELIVERED`: принимающая сторона приняла
            сообщение. `FAILED`: принимающая сторона отклонила его или последняя
            попытка завершилась неудачей.
        rail:
          type: string
          enum:
            - INTERNAL
            - TRP
            - GTR
            - TRUST
            - VERIFYVASP
            - SYGNA
            - EMAIL
            - ''
          description: >-
            Транспортная сеть (rail), передающая сообщение. Пусто до тех пор,
            пока Didit не выберет её для первого сообщения.
        attempts:
          type: integer
          minimum: 0
          description: >-
            Количество попыток, сделанных для этого сообщения на данный момент.
            Для сообщения, не являющегося опросом статуса, выполняется не более
            6 попыток.
        last_error:
          type: string
          description: >-
            Тип сбоя, возникшего при последней попытке, либо `""`, если сбоев не
            было: например `email undeliverable`, `trp identity endpoint
            unreachable` или `trp transfer inquiry delivery failed`. Он никогда
            не содержит собственный ответ контрагента, который сохраняется в
            `timeline` перевода.

            Когда GTR возвращает ошибку, включаются собственный код состояния и
            сообщение. Тела ответов никогда не включаются.
          example: email undeliverable
        next_attempt_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Время следующей попытки, пока сообщение находится в статусе `QUEUED`
            или `RETRYING`.
        delivered_at:
          type: string
          format: date-time
          nullable: true
          description: Время получения сообщения другой стороной.
    TravelRuleDiscoveryStep:
      type: object
      description: >-
        Один шаг поиска контрагента, выполненный Didit для исходящего перевода,
        в порядке их выполнения. Первый шаг, определяющий VASP с доступным
        маршрутом, завершает цепочку.
      properties:
        step:
          type: string
          enum:
            - internal_address_book
            - wallet_attribution
            - network_lookup
            - customer_hint
            - end_user
          description: >-
            `internal_address_book`: другой клиент Didit, подтвердивший контроль
            над кошельком назначения. `wallet_attribution`: атрибуция
            блокчейн-аналитики кошелька. `network_lookup`: сеть, способная
            определить, какой VASP управляет адресом. `customer_hint`: имя VASP,
            LEI или юрисдикция, переданные вами в `beneficiary_data`.
            `end_user`: контрагент, выбранный конечным пользователем (или вами),
            либо запрос на его выбор.
        outcome:
          type: string
          enum:
            - match
            - miss
            - skipped
          description: >-
            `match`: шаг определил контрагента. `miss`: шаг был выполнен, но
            совпадений не найдено. `skipped`: шаг не удалось выполнить, причина
            указана в `reason`.
        reason:
          type: string
          description: >-
            Машиночитаемая причина, `""` при совпадении:
            `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` или `picked_member_without_proven_wallet`.
        vasp:
          type: string
          format: uuid
          nullable: true
          description: VASP из каталога, указанный на данном шаге, если он был указан.
        rail:
          type: string
          nullable: true
          description: >-
            Транспортная сеть (rail), через которую достигается этот контрагент,
            если шаг её обнаружил.
        at:
          type: string
          format: date-time
    TravelRuleNextAction:
      type: object
      description: >-
        Одно действие, которое позволяет продвинуть перевод со статусом
        `COUNTERPARTY_VASP_NOT_FOUND` или `COUNTERPARTY_VASP_NOT_REACHABLE`. См.
        раздел [Почему перевод
        завис](/ru/transaction-monitoring/travel-rule#почему-перевод-застрял).
      properties:
        action:
          type: string
          enum:
            - select_counterparty_vasp
            - declare_self_hosted
            - add_vasp_hint
            - update_compliance_email
            - resend
          description: >-
            `select_counterparty_vasp`: конечный пользователь выбирает VASP
            назначения в виджете владения кошельком, либо вы отправляете PATCH с
            `action=beneficiary_vasp`. `declare_self_hosted`: конечный
            пользователь объявляет кошелёк некастодиальным в виджете.
            `add_vasp_hint`: укажите Didit, кто является контрагентом, с помощью
            названия VASP, LEI или Travel Address (например, `travel_address` в
            записи адресной книги кошелька назначения), затем повторите
            отправку. `update_compliance_email` и `resend` являются значениями
            `action` для `PATCH /v3/transactions/{transaction_id}/travel-rule/`:
            передайте адрес электронной почты комплаенс-службы контрагента
            повторно и перезапустите маршрутизацию.
        url:
          type: string
          format: uri
          description: >-
            Ссылка на виджет подтверждения владения кошельком, при
            `select_counterparty_vasp` и `declare_self_hosted`, пока у перевода
            есть открытая сессия виджета.
      required:
        - action
    TravelRuleChainDetails:
      type: object
      description: >-
        Как блокчейн перевода именует два своих кошелька, когда перевод
        выполняется не просто с одного адреса на другой. Пусто (`{}`) для
        переводов в сетях на основе аккаунтов (EVM, Solana, Tron), где эти два
        адреса и есть кошельки. Сопоставление, маршрутизация и адресная книга
        читают кошельки в первую очередь отсюда.
      properties:
        chain:
          type: string
          description: >-
            Каноническая сеть, например `BTC`, `XRP` или `LIGHTNING` для
            перевода через Lightning.
        shape:
          type: string
          enum:
            - utxo
            - memo
            - lightning
        originator:
          $ref: '#/components/schemas/TravelRuleChainSide'
        beneficiary:
          $ref: '#/components/schemas/TravelRuleChainSide'
        utxo:
          type: object
          description: >-
            Для перевода UTXO: входы и выходы в сохраненном виде (суммы в виде
            десятичных строк) и то, как именно Didit интерпретировал выходы.
          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: Выходы, возвращающие средства обратно на адрес входа.
            beneficiary_output_index:
              type: integer
              nullable: true
              description: >-
                Выход, выплачивающий средства получателю; null, если не удалось
                определить ни один.
        lightning:
          type: object
          description: >-
            Для перевода Lightning: содержимое платежного запроса. Всегда `kind`
            (`bolt11`, `bolt12_offer`, `bolt12_invoice`,
            `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id`
            или `unknown`); инвойс BOLT11 добавляет `network`, `payee_node_id`,
            `payment_hash`, `amount_msat`, `created_at` и `expires_at`; строка
            BOLT12 добавляет `blinded_paths` и `payee_node_id`; LNURL или
            Lightning Address добавляет свой `domain`. По сети ничего не
            запрашивается: выполняется только декодирование запроса.
          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: >-
            Несоответствия UTXO, заслуживающие внимания: заявленный отправитель
            отсутствует во входах (inputs), заявленный получатель отсутствует в
            выходах (outputs), невозможно выделить единственный выход получателя
            или сумма в выходе получателя отличается от указанной в транзакции.
        not_applicable_reason:
          type: string
          enum:
            - LIGHTNING_NO_PAYEE_IDENTIFIER
            - LIGHTNING_BOLT12_BLINDED_PAYEE
            - LIGHTNING_LNURL_NAMES_NO_PAYEE
          description: >-
            Для исходящего перевода Lightning, в платежном запросе которого не
            указан получатель: причина, почему перевод имеет статус
            `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (в запросе не
            указан узел получателя или запрос не удалось декодировать),
            `LIGHTNING_BOLT12_BLINDED_PAYEE` (предложение скрывает своего
            получателя за слепыми путями), `LIGHTNING_LNURL_NAMES_NO_PAYEE`
            (LNURL указывает сервис, а не получателя). Тот же код открывает
            последнюю запись `timeline` перевода.
    TravelRuleChainSide:
      type: object
      description: Кошелёк одной из сторон, определённый Didit на основе данных блокчейна.
      properties:
        address:
          type: string
          description: >-
            Кошелёк. В сетях с memo это классический адрес (XRP X-address
            разделяется на классический адрес и тег); в Lightning это
            идентификатор узла получателя или Lightning Address.
        memo:
          type: string
          description: >-
            Destination tag или memo, являющиеся частью кошелька; `""`, если
            отсутствует.
        source:
          type: string
          enum:
            - declared
            - x_address
            - largest_input
            - only_non_change_output
            - amount_match
            - invoice_payee
            - updated
          description: >-
            Откуда получен кошелёк: `declared` (ваш запрос), `x_address`
            (выделен из X-адреса XRP), `largest_input` (входной адрес UTXO с
            наибольшим вкладом), `only_non_change_output` (единственный выход
            UTXO, не являющийся сдачей), `amount_match` (единственный выход
            UTXO, выплачивающий сумму перевода), `invoice_payee` (получатель,
            указанный в платежном запросе Lightning), `updated` (установлен
            позже с помощью `action: update_originator_wallet`).
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API-ключ вашего приложения из раздела «Разработчикам» -> «API-ключи» в
        Business Console. Основной ключ имеет полный доступ. Именованный ключ
        может иметь ограниченную область действия: без доступа, чтение или
        запись для каждого ресурса, ограничение определенными сценариями или
        одобренными сессиями, списком IP-адресов и сроком действия. 401
        означает, что ключ неверен, отозван или его срок действия истек; 403
        означает, что ключ не был передан, у ключа нет доступа к этому ресурсу
        или действию, либо запрос поступил с адреса вне его списка IP-адресов;
        404 на маршруте сессии означает, что сессия не входит в сценарии или
        статусы ключа. Ключ без доступа к медиа получает URL изображений, видео
        и PDF как null, а ключ без прав на запись сессий получает ссылки на
        сессии и токены как null. См. https://docs.didit.me/console/api-keys.

````

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