# Create a transaction

### Prerequisite

Your API Operator must [be authenticated](https://help.enterprise.ledger.com/api-documentation/tutorials/first-steps-as-an-api-user/authenticate-as-an-api-user) to perform the following steps.

### Create a Transaction

#### Building your request payload:

To build a payload to create a new outgoing transaction request, we just need to know:

* the sender account, in our case let's use one account from the previous payload; the account named `ClientA COL TBTC 1` , id `2` .
* the recipient `address` , let's use `tb1q5tsjcyz7xmet07yxtumakt739y53hcttmntajq`
* the amount we want to send, let's say `2` tBTC

We will need to create `CREATE_TRANSACTION` request type for the requests endpoint. Then in `data` we will be passing the transaction intention following the specifications depending on each type of transaction, since we are using a bitcoin testnet account, we need to be following the `"transaction_type": "BITCOIN_LIKE_SEND",`, we know this from the account object we received earlier of `"type": "Bitcoin",`.

You can check the requests endpoint on how to specify the `fees_strategy` for each `transaction_type`. In our case we will follow the standard fee priotity model, FAST, to make sure our transaction is processed quickly by the node.

We also need to build up the `transaction_data` object, in this object you will specify more precisly your intention, it's redondent yet it allows a better security validation of the challenge later on. In our case we need to :

* A `currency` should be the same as the one in your account in this case `bitcoin_testnet` , this allow the HSM to validate he is signing for the good derivation path and prevent an attacker to switch this derivation path to your main `bitcoin` account without you knowing.
* Sender `account_name` which is the unique identifier of your account on the HSM, in our case `ClientA COL TBTC 1`
* A `max_fees` it's the highest amount of fees in the blockchain asset your are willing to pay for in this transaction, this is used to assert the transaction at a signature level when HSM sees that the crafted Tx is spending more in fees that what you specify here. And since fees can vary from the type you create the tx to the time it get signed by all of the other operator, it's generally good to include a buffer, the estimate fees endpoint and following section help you select this value. You can also set your own based on the max amount you are willing to pay it's acting as an extra security
* The `recipient` , use the address you want to send BTC to `tb1q5tsjcyz7xmet07yxtumakt739y53hcttmntajq`
* The `amount` you want to send in the smallest unit of this asset. You can use the get currency by name endpoint to get all of the information about the currency you are using. To convert your 2tBTC in tsat you need to get the magnitude of the currency `bitcoin_testnet` . In our case the tBTC magnitude is `8` it means that I need to multiply the amount in tBTC by this magnitude to get the amount for this payload in satoshis (tsat) so `2 * 10^8 = 200000000` .

The resulting request payload is the following:

```json
{
  "data": {
    "account_id": "2",
    "type": "CREATE_TRANSACTION",
    "transaction_data": {
      "account_name": "ClientA COL TBTC 1",
      "amount": "200000000",
      "currency": "bitcoin_testnet",
      "max_fees": ""{{max_fees_from_estimate_fees_endpoint}}"",
      "recipient": "tb1q5tsjcyz7xmet07yxtumakt739y53hcttmntajq"
    },
    "transaction_type": "BITCOIN_LIKE_SEND"
  },
  "fees_strategy": {
      "data": {
        "speed": "FAST"
      },
      "type": "SPEED"      
    }
}
```

#### Estimate & define fees:

The use the same payload to compute the recommended fees and max*fees by calling the \[transactions/estimate-fees endpoint (/openapi/le*api/tag/Transactions/paths/\~1transactions\~1estimate-fees/post/) endpoint. You can also define custom fees and advanced options please refer to the [fees & speed](https://help.vault.ledger.com/developer-portal/content/transactions/tx/) section of the help center for more informations.

{% tabs %}
{% tab title="Bash" %}

```bash
curl --request POST \
  --url https://api.vault.ledger.com/transactions/estimate-fees \
  --header 'authorization: Bearer {{access_token}}' \
  --header 'content-type: application/json' \
  --header 'x-ledger-workspace: minivault' \
  --data '{
    "account_id": "2",
    "type": "CREATE_TRANSACTION",
    "transaction_data": {
      "account_name": "ClientA COL TBTC 1",
      "amount": "200000000",
      "currency": "bitcoin_testnet",
      "max_fees": ""{{max_fees_from_estimate_fees_endpoint}}"",
      "recipient": "tb1q5tsjcyz7xmet07yxtumakt739y53hcttmntajq"
    },
    "transaction_type": "BITCOIN_LIKE_SEND"
  },
  "fees_strategy": {
      "data": {
        "speed": "FAST"
      },
      "type": "SPEED"
            }
        }
    }
}'
```

{% endtab %}

{% tab title="JSON" %}

```json
{
  "coin_fields": {
    "UTXO_limit": 150,
    "fees_per_byte": 0,
    "type": "Bitcoin"
  },
  "max_fees": "211",
  "max_fees_buffer_factor": 1.5
}
```

{% endtab %}
{% endtabs %}

If the response status is 200, the response payload will have the attribute `max_fees`, you can use it in your initial payload, for the following step we will refer to this value with `max_fees_from_estimate_fees_endpoint`.

#### POST Create Transaction request:

Then create the actual transaction request with the same payload except that the max\_fees value must be relevant, use the one extracted in the previous step.

{% tabs %}
{% tab title="Bash" %}

```bash
curl --request POST \
  --url https://api.vault.ledger.com/requests \
  --header 'authorization: Bearer {{access_token}}' \
  --header 'content-type: application/json' \
  --header 'x-ledger-workspace: minivault' \
  --data '{
    "account_id": "2",
    "type": "CREATE_TRANSACTION",
    "transaction_data": {
      "account_name": "ClientA COL TBTC 1",
      "amount": "200000000",
      "currency": "bitcoin_testnet",
      "max_fees": ""{{max_fees_from_estimate_fees_endpoint}}"",
      "recipient": "tb1q5tsjcyz7xmet07yxtumakt739y53hcttmntajq"
    },
    "transaction_type": "BITCOIN_LIKE_SEND"
  },
  "fees_strategy": {
      "data": {
        "speed": "FAST"
      },
      "type": "SPEED"
            }
        }
    }
}'
```

{% endtab %}

{% tab title="JSON" %}

```json
{
  "created_by": {
    "id": 24
  },
  "created_on": "2024-01-24T08:07:08.007892+00:00",
  "expired_at": "2024-01-31T08:07:08.007837+00:00",
  "id": 29,
  "status": "PENDING_APPROVAL",
  "target_id": 305,
  "target_type": "BITCOIN_LIKE_TRANSACTION",
  "type": "CREATE_TRANSACTION"
}
```

{% endtab %}
{% endtabs %}

Once the transaction is created, it can be approved by the different operators in the transaction rules. Transaction rules can vary from an account to the other. It'll affect how you create transactions as the amount per transaction can be limited (Amount ranges) as well as the possible list of allowed recipients (Whitelisted addresses). To find out which rules have been defined in an account, go to Accounts > Account dashboard > Rules tab.

{% hint style="info" %}
The attribute `target_id` of a request in our example of type `CREATE_TRANSACTION` provides the id of the transaction.
{% endhint %}

Once this is done, the next important step is [approving the request](https://help.enterprise.ledger.com/api-documentation/tutorials/api-functionalities/approve-a-request) so the transaction is created.
