# Travel Rule Compliance

## What is Travel Rule?

As part of our commitment to ensuring transparency of transactions, we will soon be introducing Travel Rule requirements, in line with Markets in Crypto-assets Regulation, Transfer of Funds Regulation and other relevant national legislation. The Travel Rule mandates that certain information about the sender and receiver of transactions be securely transmitted to ensure compliance with anti-money laundering (AML) and counter-terrorist financing (CTF) measures.

Specifically, the following data will be required:

For individuals:

* Full name

For legal entities:

* Company name

Additionally, we will be requesting confirmation regarding whether the funds are sent to/from a hosted (custodial) or unhosted (non-custodial) wallet for the transactions exceeding 1,000 EUR (or its equivalent in other currencies). For hosted wallets, the name of the platform hosting the wallet will be requested, while for non-custodial ones, we will request confirmation via a declaration of wallet ownership.

## How does it affect API transactions?

For those who rely on API request to initiate certain operations, new API query parameters will be introduced for coin withdrawals (payouts) and invoice refunds (sent to external wallets), i.e. any outbound crypto operations.&#x20;

If you are ready to comply with Travel Rule and provide the information about the transactions on your account, these parameters would have to be included in the request. An example of API [request](https://reference.cryptopay.me/#tag/Coin-withdrawals/operation/coin-withdrawals.create) for a Coin Withdrawal will look like this:

```
curl -X "POST" "https://business.cryptopay.me/api/coin_withdrawals" \
     -H 'Authorization: HMAC ***' \
     -H 'Content-Type: application/json' \
     -H 'Date: Tue, 28 Jan 2025 08:18:20 GMT' \
     -d $'{
  "address": "2Mz3bcjSVHG8uQJpNjmCxp24VdTjwaqmFcJ",
  "charged_currency": "EUR",
  "received_currency": "BTC",
  "network": "bitcoin",
  "charged_amount": "100.0",
  "travel_rule_compliant": true,
  "beneficiary": {
    "type": "natural_person",
    "name": "John Doe"
   },
  "force_commit": true
}'
```

Let’s go through the parameters specific to Travel Rule:

* `travel_rule_compliant` – is `false` if omitted. Set to `true` to turn on beneficiary data validations and comply with Travel Rule, and the following parameters have to be added:
* `beneficiary` - required, object:
  * `type` - required, string enum – refers to beneficiary type, can be `legal_person` or `natural_person`;
  * `name` - required, string (≤100 characters) – the registered name of the company for a `legal_person` or the full name for a `natural_person`.;
  * &#x20;`address` - optional, object:
    * `country` - optional, string (≤2 characters) – the 2-letter ISO country code of the address
    * `city` - optional, string (≤35 characters) – the city of the address.&#x20;
    * `line_1` - optional, string (≤70 characters) – first line of the address.
    * `line_2` - optional, string (≤70 characters) – second line of the address.
    * `post_code` - optional, string (≤16 characters) – postal code of the address.

If the withdrawal request was made correctly, you'll get a `201` response from our server:

```
{
"data": {
    "id": "f8d24a8b-72c2-42fb-8b4e-a36230d572b3",
    "custom_id": null,
    "customer_id": null,
    "address": "2Mz3bcjSVHG8uQJpNjmCxp24VdTjwaqmFcJ",
    "network": "bitcoin",
    "txid": null,
    "status": "pending",
    "charged_amount": "100.0",
    "charged_currency": "EUR",
    "received_amount": "0.00184519",
    "received_currency": "BTC",
    "network_fee": "0.00000216",
    "network_fee_level": "average",
    "fee": "0.0",
    "fee_currency": "BTC",
    "exchange": {
        "pair": "BTCEUR",
        "rate": "39711.9618",
        "fee": "0.0",
        "fee_currency": "EUR"
        },
    "risk": {
        "score": 0,
        "level": "low",
        "resource_name": "Bitstamp",
        "resource_category": "Exchange"
    },
    "created_at": "2019-08-24T14:15:22Z"
    }
}
```

If `travel_rule_compliant` is set to `true` in the request, but the required beneficiary data is not provided (i.e. the `beneficiary` object is missing), you will get an error `beneficiary_required` with http status `422` in response:

```
{
  "error": {
    "code": "beneficiary_required",
    "message": "beneficiary required",
    "args": {
      "verification_url": "https://business-hosted.cryptopay.me/counterparties/3419ee7b-3215-4d0a-bdce-e7643049b69d"
    },
    "details": []
  },
  "meta": {
    "request_id": "e03fdd02910535ac358b34a1831842e1"
  }
}
```

`args.verification_url` contains a URL where the user can be redirected to provide the data by filling in the required Travel Rule fields. Once completed, the next request with the same parameters will be processed successfully (`201`).

In addition to [coin withdrawals](https://reference.cryptopay.me/#tag/Coin-withdrawals/operation/coin-withdrawals.create), the `travel_rule_compliant` parameter and `beneficiary` object can be used with refund of invoices (if they are made to an external wallet address, not the merchant account). Such a request will look as follows:

```
curl -X "POST" https://business.cryptopay.me/api/invoices/782a9ad2-83c0-43df-9021-3cae9d843d32/refunds \
     -H 'Authorization: HMAC ***' \
     -H 'Content-Type: application/json' \
     -H 'Date: Tue, 28 Jan 2025 08:18:20 GMT' \
     -d $'{
  "address": "2MyYeAkU162aMh3otEhYHP9yhUR7xqS7S1r",
  "travel_rule_compliant": true,
  "beneficiary": {
    "type": "natural_person",
    "name": "John Doe"
   },
}'
```

Same as coin withdrawal, you'll receive `201` response if the request is successful. If the beneficiary data is not provided (i.e. the `beneficiary` object is missing), you will get an error `beneficiary_required` with http status `422` in response – please refer to the example above.
