curl --request POST \
--url https://api.vitawallet.io/api/businesses/transactions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'x-date: <api-key>' \
--header 'x-login: <api-key>' \
--header 'x-trans-key: <api-key>' \
--data '
{
"transactions_type": "exchange",
"currency_sent": "usd",
"currency_received": "usdt",
"amount_sent": 10,
"order": "AAA0008"
}
'import requests
url = "https://api.vitawallet.io/api/businesses/transactions"
payload = {
"transactions_type": "exchange",
"currency_sent": "usd",
"currency_received": "usdt",
"amount_sent": 10,
"order": "AAA0008"
}
headers = {
"x-login": "<api-key>",
"x-trans-key": "<api-key>",
"x-date": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-login': '<api-key>',
'x-trans-key': '<api-key>',
'x-date': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
transactions_type: 'exchange',
currency_sent: 'usd',
currency_received: 'usdt',
amount_sent: 10,
order: 'AAA0008'
})
};
fetch('https://api.vitawallet.io/api/businesses/transactions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vitawallet.io/api/businesses/transactions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'transactions_type' => 'exchange',
'currency_sent' => 'usd',
'currency_received' => 'usdt',
'amount_sent' => 10,
'order' => 'AAA0008'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"x-date: <api-key>",
"x-login: <api-key>",
"x-trans-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vitawallet.io/api/businesses/transactions"
payload := strings.NewReader("{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-login", "<api-key>")
req.Header.Add("x-trans-key", "<api-key>")
req.Header.Add("x-date", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vitawallet.io/api/businesses/transactions")
.header("x-login", "<api-key>")
.header("x-trans-key", "<api-key>")
.header("x-date", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vitawallet.io/api/businesses/transactions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-login"] = '<api-key>'
request["x-trans-key"] = '<api-key>'
request["x-date"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7b16a281-450c-40e9-978eedc17483-02273",
"type": "business_transaction",
"attributes": {
"status": "completed",
"origin_currency": "usd",
"destination_currency": "usdt",
"amount_sent": 10,
"amount_received": 9.96,
"rate": 0.9965,
"order": "AAA000811",
"created_at": "2026-04-28T18:51:13.188Z"
}
}Create exchange
Create a crypto exchange transaction. This endpoint converts funds between a crypto and a fiat currency (in either direction) or between two cryptocurrencies, directly from your business wallet at the rate retrieved from GET /crypto_prices.
Note: This endpoint shares a URL with the other transaction creation flows (
vita_sent,withdrawal,crypto_payout). Thetransactions_typefield is the discriminator — set it to"exchange"for a crypto exchange.
Request Structure
| Key | Description |
|---|---|
transactions_type | Must be set to "exchange" for a crypto exchange. |
currency_sent | Source currency to exchange from (e.g., "usd", "btc", "usdt"). Must be active in your wallet. |
currency_received | Destination currency to exchange to (e.g., "btc", "usdt", "usd"). |
amount_sent | Amount to exchange from the source currency (e.g., 100, 105.65). |
order | Unique order identifier for this exchange transaction. Used as idempotency key. |
Supported Exchange Types
| Type | Direction |
|---|---|
| Fiat → Crypto | USD, CLP, COP, MXN, ARS → BTC, USDT, USDC |
| Crypto → Fiat | BTC, USDT, USDC → USD, CLP, COP, MXN, ARS |
| Crypto → Crypto | BTC ↔ USDT, BTC ↔ USDC, USDT ↔ USDC |
⚠️ Not supported: Fiat → Fiat exchanges (e.g., USD → CLP, COP → MXN) are rejected with a
305error. At least one ofcurrency_sentorcurrency_receivedmust be a cryptocurrency.
Important Considerations
Price Validity
-
Exchange rates come exclusively from
GET /crypto_prices, which returns avalid_untiltimestamp. -
If the price has expired when you submit, the API returns
"Los precios han caducado, por favor intente de nuevo". Request/crypto_pricesagain before retrying. -
The
ratereturned in the exchange response reflects the price used from the most recent/crypto_pricesconsultation.
Balance Requirements
-
Both the source and destination currencies must be active in your wallet.
-
The source balance must be enough to cover
amount_sent.
Minimum Amount
- Each
currency_senthas a minimum exchange amount. Submitting below the minimum returns an error withmin_exchange_amountandmin_exchange_currencyso you can present it to the end user.
Processing Time
- Exchanges settle instantly once a valid price is confirmed.
Signature Coverage
- All exchange parameters — including
transactions_type— must be included in the signature validation.
Request Example
{
"transactions_type": "exchange",
"currency_sent": "usd",
"currency_received": "usdt",
"amount_sent": 10,
"order": "AAA0008"
}
Quick Recap
-
Confirm crypto exchange is enabled on your business account.
-
Call
GET /api/businesses/crypto_pricesto retrieve the current_sellrate andvalid_until. -
Verify
amount_sentmeets the minimum forcurrency_sentand that your source balance covers it. -
Make sure at least one of
currency_sent/currency_receivedis a cryptocurrency. -
Generate a unique
orderID and submit the exchange toPOST /api/businesses/transactionswithtransactions_type: "exchange"beforevalid_untilexpires. -
If the response times out, query
GET /api/businesses/transactions?order=<your_order>before retrying — never reuse the request with a neworder.
curl --request POST \
--url https://api.vitawallet.io/api/businesses/transactions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'x-date: <api-key>' \
--header 'x-login: <api-key>' \
--header 'x-trans-key: <api-key>' \
--data '
{
"transactions_type": "exchange",
"currency_sent": "usd",
"currency_received": "usdt",
"amount_sent": 10,
"order": "AAA0008"
}
'import requests
url = "https://api.vitawallet.io/api/businesses/transactions"
payload = {
"transactions_type": "exchange",
"currency_sent": "usd",
"currency_received": "usdt",
"amount_sent": 10,
"order": "AAA0008"
}
headers = {
"x-login": "<api-key>",
"x-trans-key": "<api-key>",
"x-date": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-login': '<api-key>',
'x-trans-key': '<api-key>',
'x-date': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
transactions_type: 'exchange',
currency_sent: 'usd',
currency_received: 'usdt',
amount_sent: 10,
order: 'AAA0008'
})
};
fetch('https://api.vitawallet.io/api/businesses/transactions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vitawallet.io/api/businesses/transactions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'transactions_type' => 'exchange',
'currency_sent' => 'usd',
'currency_received' => 'usdt',
'amount_sent' => 10,
'order' => 'AAA0008'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"x-date: <api-key>",
"x-login: <api-key>",
"x-trans-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vitawallet.io/api/businesses/transactions"
payload := strings.NewReader("{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-login", "<api-key>")
req.Header.Add("x-trans-key", "<api-key>")
req.Header.Add("x-date", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vitawallet.io/api/businesses/transactions")
.header("x-login", "<api-key>")
.header("x-trans-key", "<api-key>")
.header("x-date", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vitawallet.io/api/businesses/transactions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-login"] = '<api-key>'
request["x-trans-key"] = '<api-key>'
request["x-date"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"transactions_type\": \"exchange\",\n \"currency_sent\": \"usd\",\n \"currency_received\": \"usdt\",\n \"amount_sent\": 10,\n \"order\": \"AAA0008\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7b16a281-450c-40e9-978eedc17483-02273",
"type": "business_transaction",
"attributes": {
"status": "completed",
"origin_currency": "usd",
"destination_currency": "usdt",
"amount_sent": 10,
"amount_received": 9.96,
"rate": 0.9965,
"order": "AAA000811",
"created_at": "2026-04-28T18:51:13.188Z"
}
}Authorizations
Business xLogin
Business xTransKey
ISO8601 datetime
V2-HMAC-SHA256 signature. Example: V2-HMAC-SHA256, Signature: <hash>
Body
Must be "exchange" for a crypto exchange transaction.
exchange Source currency (ISO code, lowercase). Must be active in your wallet.
"usd"
Destination currency (ISO code, lowercase).
"usdt"
Amount to exchange from the source currency.
10
Unique order identifier (idempotency key).
"AAA0008"
Response
Exchange created successfully.