Travel Rule Compliance

API parameters used for 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:

  • First name, Last name

  • Country, Address, Zip code

For legal entities:

  • Company name

  • Country, Address, Zip code

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.

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

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

      • 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, 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.

Last updated

Was this helpful?