curl --request POST \
--url https://whitebit.com/api/v4/convert/auto-confirm \
--header 'Content-Type: application/json' \
--header 'X-TXC-APIKEY: <api-key>' \
--header 'X-TXC-PAYLOAD: <api-key>' \
--header 'X-TXC-SIGNATURE: <api-key>' \
--data '
{
"from": "BTC",
"to": "USDT",
"direction": "from",
"amount": "0.1",
"idempotencyKey": "9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240"
}
'import requests
url = "https://whitebit.com/api/v4/convert/auto-confirm"
payload = {
"from": "BTC",
"to": "USDT",
"direction": "from",
"amount": "0.1",
"idempotencyKey": "9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240"
}
headers = {
"X-TXC-APIKEY": "<api-key>",
"X-TXC-PAYLOAD": "<api-key>",
"X-TXC-SIGNATURE": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-TXC-APIKEY': '<api-key>',
'X-TXC-PAYLOAD': '<api-key>',
'X-TXC-SIGNATURE': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'BTC',
to: 'USDT',
direction: 'from',
amount: '0.1',
idempotencyKey: '9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240'
})
};
fetch('https://whitebit.com/api/v4/convert/auto-confirm', 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://whitebit.com/api/v4/convert/auto-confirm",
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([
'from' => 'BTC',
'to' => 'USDT',
'direction' => 'from',
'amount' => '0.1',
'idempotencyKey' => '9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-TXC-APIKEY: <api-key>",
"X-TXC-PAYLOAD: <api-key>",
"X-TXC-SIGNATURE: <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://whitebit.com/api/v4/convert/auto-confirm"
payload := strings.NewReader("{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-TXC-APIKEY", "<api-key>")
req.Header.Add("X-TXC-PAYLOAD", "<api-key>")
req.Header.Add("X-TXC-SIGNATURE", "<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://whitebit.com/api/v4/convert/auto-confirm")
.header("X-TXC-APIKEY", "<api-key>")
.header("X-TXC-PAYLOAD", "<api-key>")
.header("X-TXC-SIGNATURE", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://whitebit.com/api/v4/convert/auto-confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-TXC-APIKEY"] = '<api-key>'
request["X-TXC-PAYLOAD"] = '<api-key>'
request["X-TXC-SIGNATURE"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}"
response = http.request(request)
puts response.read_bodyConvert Auto Confirm
The endpoint requests a conversion quote and accepts it in a single call. No separate confirm step and no expiry window apply, so the 10-second quote lifetime that governs Convert Estimate followed by Convert Confirm cannot elapse mid-flow. The trade (spot) balance funds the conversion and receives the converted amount, matching the two-step flow. When the source currency is not on the trade balance, the request fails with the insufficient-balance error (400, code 37) and no funds move.
The endpoint reports a conversion as executed only when the quote is filled and the converted amount is non-zero.
A 200 response means the conversion executed. Two 200 responses with the same id come only from two requests with the same idempotencyKey, and describe one conversion. Key the integration’s ledger on id.
idempotencyKey makes a retry safe. The key is scoped to the authenticated account. The endpoint claims the key before executing anything. The first request claims the key and converts; for 24 hours, a repeated request with the same key returns the recorded response (a 200 or a 502) without converting again. A duplicate that arrives while the first request is still running waits up to 3 seconds, then returns 409 under errors.request; retry later with the same key. A request that fails before anything was executed frees the key, so a retry converts. Without a key, a retry converts a second time. The endpoint checks the key length on the string and never compares a digits-only key as a number, so "12345678" is valid and "123" is too short.
The key is bound to the request that first executed it.
The id returned on success is the quote ID of the executed conversion and is accepted as the quoteId filter on Convert History.
Convert History does not filter by idempotency key. To recover the outcome of a request sent with a key, resend the identical request with the same key within 24 hours; the endpoint returns the original response, including id. A request that reuses a key from a different request returns 409. Without a key, after a 502, or after 24 hours, search the history by time window, pair, and amounts.
The endpoint validates the request in stages. An empty body reports only from and to under errors; the endpoint checks direction and amount once from and to are present, so a request that fixes an empty-body 422 can receive a second 422 for the remaining parameters.
An amount outside 0.00000001–100000000000 returns 422 with code 30 under errors.amount. The endpoint still rejects an amount inside the allowed range as too small (422, code 0) when the amount is worth less than 0.00000001 of the target asset at current rates; the minimum is pair-dependent. Send amount as a string. The endpoint currently tolerates a JSON number for amount but can lose precision beyond approximately 15 significant digits, and the conversion executes with the rounded amount: 12345678901.12345678 sent as a JSON number executes as 12345678901.123457. Do not rely on the tolerance.
from and to must differ. A request with the same currency in both fields returns 422 with code 30 under errors.from.
Rate limit: 10,000 requests / 10 sec per IP address — the default for all endpoints. See Rate limits.
The claim on a key lapses after 60 seconds only when processing stops without recording an outcome, and the platform keeps a recorded outcome for 24 hours. After the claim lapses, or after 24 hours, a retry with the same key can convert a second time: check Convert History before retrying.
For errors forwarded from the conversion service — 409 and 502 — the top-level code field is 0 and the top-level message field is the generic Invalid request.. The specific condition appears in errors.<field>[0]: under errors.idempotencyKey when a different request already used the key, under errors.request otherwise. Branch on the HTTP status code and the field name rather than on code.
After a 500 or a 502, the conversion may have executed, and a retry with a new key can convert a second time. Check Convert History before converting again: a record means the conversion executed and the converted amount is on the trade balance.
Error text is not part of the contract and may change. Treat the HTTP status, the code, and the field name under errors as the stable contract.
curl --request POST \
--url https://whitebit.com/api/v4/convert/auto-confirm \
--header 'Content-Type: application/json' \
--header 'X-TXC-APIKEY: <api-key>' \
--header 'X-TXC-PAYLOAD: <api-key>' \
--header 'X-TXC-SIGNATURE: <api-key>' \
--data '
{
"from": "BTC",
"to": "USDT",
"direction": "from",
"amount": "0.1",
"idempotencyKey": "9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240"
}
'import requests
url = "https://whitebit.com/api/v4/convert/auto-confirm"
payload = {
"from": "BTC",
"to": "USDT",
"direction": "from",
"amount": "0.1",
"idempotencyKey": "9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240"
}
headers = {
"X-TXC-APIKEY": "<api-key>",
"X-TXC-PAYLOAD": "<api-key>",
"X-TXC-SIGNATURE": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-TXC-APIKEY': '<api-key>',
'X-TXC-PAYLOAD': '<api-key>',
'X-TXC-SIGNATURE': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'BTC',
to: 'USDT',
direction: 'from',
amount: '0.1',
idempotencyKey: '9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240'
})
};
fetch('https://whitebit.com/api/v4/convert/auto-confirm', 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://whitebit.com/api/v4/convert/auto-confirm",
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([
'from' => 'BTC',
'to' => 'USDT',
'direction' => 'from',
'amount' => '0.1',
'idempotencyKey' => '9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-TXC-APIKEY: <api-key>",
"X-TXC-PAYLOAD: <api-key>",
"X-TXC-SIGNATURE: <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://whitebit.com/api/v4/convert/auto-confirm"
payload := strings.NewReader("{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-TXC-APIKEY", "<api-key>")
req.Header.Add("X-TXC-PAYLOAD", "<api-key>")
req.Header.Add("X-TXC-SIGNATURE", "<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://whitebit.com/api/v4/convert/auto-confirm")
.header("X-TXC-APIKEY", "<api-key>")
.header("X-TXC-PAYLOAD", "<api-key>")
.header("X-TXC-SIGNATURE", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://whitebit.com/api/v4/convert/auto-confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-TXC-APIKEY"] = '<api-key>'
request["X-TXC-PAYLOAD"] = '<api-key>'
request["X-TXC-SIGNATURE"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"BTC\",\n \"to\": \"USDT\",\n \"direction\": \"from\",\n \"amount\": \"0.1\",\n \"idempotencyKey\": \"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240\"\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
The public WhiteBIT API key.
Base64-encoded JSON request body.
HMAC-SHA512 signature of the payload, hex-encoded. Computed as hex(HMAC-SHA512(payload, api_secret)).
Body
From currency. Example: BTC
"BTC"
To currency. Example: USDT
"USDT"
Currency that amount is given in: from for the source currency, to for the target currency.
from, to "from"
Amount as a string, such as "0.1". Range: 0.00000001 to 100000000000, inclusive; truncated to 8 decimals. A JSON number may be rounded, and the rounded value is converted.
"0.1"
Optional key, 8 to 128 characters of any kind; a UUID is typical. Omit the field instead of sending an empty string: an empty string claims no key, so a retry converts again.
8 - 128"9f1c2b7e-4d3a-4f21-9c88-6e5b0a71d240"
Nonce for request
1699260637
Request path
"{{request}}"
Response
Successful response
Quote ID of the executed conversion. Accepted as the quoteId filter on the convert history endpoint.
"987654321"
Final amount given, in the from currency. The string carries no fixed number of decimal places: 10, not 10.00000000.
"0.1"
Final amount received, in the to currency. The string carries no fixed number of decimal places.
"6543.21"
Was this page helpful?