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

# Тестовый входящий перевод VASP через API Didit

> Только песочница: Тестовый VASP Didit отправит вашему приложению входящий перевод Travel Rule. Проверьте решение, входящие и поток владения.



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



      
      

\<pre>

\`Make the Didit Test VASP send my sandbox application an inbound Travel Rule transfer, to exercise the receiving side of an exchange before going live.

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

Authentication:
Use the x-api-key header with my SANDBOX application's API key. A live application receives 400.

Request body (application/json):
\{
"beneficiary_wallet_address": "0xYourSandboxWallet",  // required: the destination wallet address
"scenario": "accept",                                // optional: accept (default) or name_mismatch
"chain": "ETH",                                      // optional
"amount": "1",                                       // optional, decimal string
"currency": "ETH",                                   // optional
"reference": "demo-001"                              // optional: repeat calls with it return the first transfer
}

Behavior:
\- The transfer is decided by the same logic a real inbound transfer runs, against my wallet address book: a verified wallet with the holder's name completes, an unverified wallet waits for ownership, a wallet with no matching address book entry is booked ON_HOLD, and name_mismatch ends as COUNTERPARTY_MISMATCHED_DATA.
\- Nothing leaves Didit. travel_rule.status.updated webhooks fire with environment "sandbox", test_vasp true and the scenario name.

What to read from the response:
\- transaction_id, txn_id - the booked inbound transaction.
\- travel_rule_status and detail - how my application decided it.
\- travel_rule - the full transfer.

Full guide: /transaction-monitoring/travel-rule#testing-without-network-credentials.`

\</pre>



      
      

Вставьте в



## OpenAPI

````yaml ru/openapi-25.json POST /v3/travel-rule/test-vasp/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/test-vasp/inbound/:
    post:
      tags:
        - Travel Rule
      summary: Инициировать входящий перевод от тестового VASP Didit (песочница)
      description: >-
        Только для приложений в песочнице. Didit Test VASP отправляет вашему
        приложению входящий перевод Travel Rule, чтобы вы могли протестировать
        принимающую сторону биржи от начала до конца перед выходом в продакшн.
        Перевод регистрируется, и решение по нему принимается по той же логике,
        которую реальный входящий перевод из сети применяет к вашей адресной
        книге кошельков, поэтому входящие сообщения, решение и процесс
        подтверждения владения кошельком работают так же, как и в продакшене. За
        пределы Didit ничего не уходит. Приложение в продакшн-среде получит
        ошибку 400. Отправьте тот же `reference` повторно, чтобы получить
        перевод, зарегистрированный первым вызовом, вместо создания второго.
      operationId: triggerTravelRuleTestVaspInbound
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TravelRuleTestVaspInboundRequest'
            example:
              beneficiary_wallet_address: 0xYourSandboxWallet
              scenario: accept
              amount: '1'
              reference: demo-001
      responses:
        '201':
          description: >-
            Входящий перевод был проведен и по нему принято решение. Повторный
            запрос с тем же `reference` возвращает то же тело ответа.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelRuleTestVaspInboundResponse'
        '400':
          description: >-
            Недопустимое тело запроса, неизвестный или неподдерживаемый
            `scenario`, либо приложение является продакшн-приложением.
          content:
            application/json:
              schema:
                type: object
        '409':
          description: >-
            Перевод не удалось провести, например, потому что Travel Rule не
            включен для приложения.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            curl -X POST
            https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \
              -H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \
              -d '{"beneficiary_wallet_address":"0xYourSandboxWallet","scenario":"accept","reference":"demo-001"}'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.transactions.travel_rule.trigger_test_vasp_inbound(
                beneficiary_wallet_address="0xYourSandboxWallet",
                scenario="accept",
                amount="1",
                reference="demo-001",
            )
            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.triggerTestVaspInbound({
              beneficiary_wallet_address: "0xYourSandboxWallet",
              scenario: "accept",
              amount: "1",
              reference: "demo-001",
            });

            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.TriggerTestVASPInbound(ctx, didit.TravelRuleTestVASPInboundRequest{\n\tBeneficiaryWalletAddress: \"0xYourSandboxWallet\",\n\tScenario:                 didit.Some(didit.TravelRuleTestVASPInboundRequestScenario(\"accept\")),\n\tAmount:                   didit.String(\"1\"),\n\tReference:                didit.String(\"demo-001\"),\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.TravelRuleTestVaspInboundRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.transactions().travelRule().triggerTestVaspInbound(TravelRuleTestVaspInboundRequest.builder()
                    .beneficiaryWalletAddress("0xYourSandboxWallet")
                    .scenario(TravelRuleTestVaspInboundRequest.Scenario.of("accept"))
                    .amount("1")
                    .reference("demo-001")
                    .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->triggerTestVaspInbound([
                'beneficiary_wallet_address' => '0xYourSandboxWallet',
                'scenario' => 'accept',
                'amount' => '1',
                'reference' => 'demo-001',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.transactions.travel_rule.trigger_test_vasp_inbound(
              beneficiary_wallet_address: "0xYourSandboxWallet",
              scenario: "accept",
              amount: "1",
              reference: "demo-001"
            )
            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.TriggerTestVaspInboundAsync(new
            TravelRuleTestVaspInboundRequest

            {
                BeneficiaryWalletAddress = "0xYourSandboxWallet",
                Scenario = new TravelRuleTestVaspInboundRequestScenario("accept"),
                Amount = "1",
                Reference = "demo-001",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    TravelRuleTestVaspInboundRequest:
      type: object
      required:
        - beneficiary_wallet_address
      properties:
        beneficiary_wallet_address:
          type: string
          description: >-
            Адрес кошелька назначения. Didit Test VASP отправляет на него
            средства, сопоставляя его с вашей адресной книгой кошельков в
            блокчейне актива. Кошелёк без соответствующей записи принимается, а
            входящая транзакция регистрируется со статусом ON_HOLD.
        scenario:
          type: string
          enum:
            - accept
            - name_mismatch
          default: accept
          description: >-
            Что Didit Test VASP заявляет о получателе. `accept` указывает
            собственное имя владельца; `name_mismatch` указывает имя, с которым
            не согласен ни один владелец. Само решение всегда остаётся за вами.
        chain:
          type: string
          default: ETH
          description: Блокчейн актива.
        amount:
          type: string
          default: '1'
          description: Сумма в виде десятичной строки.
        currency:
          type: string
          default: ETH
          description: Код актива.
        reference:
          type: string
          description: >-
            Необязательный ключ идемпотентности. Повторный запрос с тем же
            значением возвращает перевод, зафиксированный первым вызовом.
    TravelRuleTestVaspInboundResponse:
      type: object
      properties:
        transaction_id:
          type: string
          format: uuid
          description: UUID транзакции Didit входящего перевода.
        txn_id:
          type: string
          description: txn_id, сгенерированный Didit.
        scenario:
          type: string
          description: Сценарий, который был выполнен.
        travel_rule_status:
          type: string
          description: >-
            Статус, полученный в результате собственного решения вашего
            приложения.
        detail:
          type: string
          description: Почему перевод получил такой статус.
        test_vasp:
          type: boolean
          description: 'Всегда true: отправителем был Didit Test VASP.'
        travel_rule:
          $ref: '#/components/schemas/TravelRuleTransferDetail'
    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'
    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`).
    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).
  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.