curl --request GET \
--url https://secureapi.tender.cash/v1/api/wallet/balance/{address} \
--header 'authorization: <api-key>' \
--header 'x-access-id: <x-access-id>' \
--header 'x-request-id: <x-request-id>' \
--header 'x-timestamp: <x-timestamp>'const options = {
method: 'GET',
headers: {
authorization: '<api-key>',
'x-timestamp': '<x-timestamp>',
'x-request-id': '<x-request-id>',
'x-access-id': '<x-access-id>'
}
};
fetch('https://secureapi.tender.cash/v1/api/wallet/balance/{address}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://secureapi.tender.cash/v1/api/wallet/balance/{address}"
headers = {
"authorization": "<api-key>",
"x-timestamp": "<x-timestamp>",
"x-request-id": "<x-request-id>",
"x-access-id": "<x-access-id>"
}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://secureapi.tender.cash/v1/api/wallet/balance/{address}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"authorization: <api-key>",
"x-access-id: <x-access-id>",
"x-request-id: <x-request-id>",
"x-timestamp: <x-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "success",
"message": "success",
"data": {
"balances": {
"native": 0.0021,
"USDT": 8,
"USDC": 0
}
}
}{
"status": "error",
"message": "chain query param is required",
"data": null
}{
"status": "error",
"message": "INVALID_REQUEST_SIGNATURE",
"data": null
}{
"status": "error",
"message": "Too many requests. Max 30 per 60s.",
"data": null
}{
"status": "error",
"message": "Wallet service is temporarily unavailable. Please try again.",
"data": null
}Get Address Balance
Fetch the native and stablecoin balances of a subwallet address
curl --request GET \
--url https://secureapi.tender.cash/v1/api/wallet/balance/{address} \
--header 'authorization: <api-key>' \
--header 'x-access-id: <x-access-id>' \
--header 'x-request-id: <x-request-id>' \
--header 'x-timestamp: <x-timestamp>'const options = {
method: 'GET',
headers: {
authorization: '<api-key>',
'x-timestamp': '<x-timestamp>',
'x-request-id': '<x-request-id>',
'x-access-id': '<x-access-id>'
}
};
fetch('https://secureapi.tender.cash/v1/api/wallet/balance/{address}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://secureapi.tender.cash/v1/api/wallet/balance/{address}"
headers = {
"authorization": "<api-key>",
"x-timestamp": "<x-timestamp>",
"x-request-id": "<x-request-id>",
"x-access-id": "<x-access-id>"
}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://secureapi.tender.cash/v1/api/wallet/balance/{address}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"authorization: <api-key>",
"x-access-id: <x-access-id>",
"x-request-id: <x-request-id>",
"x-timestamp: <x-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "success",
"message": "success",
"data": {
"balances": {
"native": 0.0021,
"USDT": 8,
"USDC": 0
}
}
}{
"status": "error",
"message": "chain query param is required",
"data": null
}{
"status": "error",
"message": "INVALID_REQUEST_SIGNATURE",
"data": null
}{
"status": "error",
"message": "Too many requests. Max 30 per 60s.",
"data": null
}{
"status": "error",
"message": "Wallet service is temporarily unavailable. Please try again.",
"data": null
}x-access-id, x-request-id, x-timestamp, and an HMAC-SHA256
authorization signature. See Authentication.currency, you get every balance Tender
tracks for the address. With currency, you get a single number.
Balances are cached for 180 seconds, so a deposit or transfer can take up to three minutes to
show here. Use the deposit and transfer webhooks for real-time updates.
Example
// All balances
const all = await fetch(`${BASE}/wallet/balance/0x4f2a9b...?chain=ethereum`, {
headers: makeHeaders(),
});
const { data } = await all.json();
// data.balances → { native: 0.0021, USDT: 8, USDC: 0 }
// One currency
const one = await fetch(`${BASE}/wallet/balance/0x4f2a9b...?chain=ethereum¤cy=usdt`, {
headers: makeHeaders(),
});
const { data: single } = await one.json();
// single.balance → 8
res = requests.get(
f"{BASE}/wallet/balance/0x4f2a9b...",
params={"chain": "ethereum", "currency": "usdt"},
headers=make_headers(),
)
balance = res.json()["data"]["balance"]
# balance → 8
Headers
{"timeStamp":"<x-timestamp>","requestId":"<x-request-id>","accessId":"<x-access-id>"}, signed with your access secret. The request body is not part of the signature.Example: "pV3n0o8kq0lK2mJ8bZ1yq3Yt6hR0cXK9u4mVJ2l9sE0=""2026-10-15T09:45:53.000Z""550e8400-e29b-41d4-a716-446655440000""your-access-id-here"Path Parameters
"0x4f2a9b..."Query Parameters
ethereum, tron or bitcoin.Example: "ethereum"USDT, usdc, ETH). It must
be supported on chain. Omit it to get all balances.Example: "USDT"Response
"success""success"currency.Show data without currency
Show data without currency
Show data with currency
Show data with currency
0 if the balance could not be
read.Example: 8Error responses
| Condition | Status | Message |
|---|---|---|
chain missing | 400 | chain query param is required |
| Chain not recognised | 400 | invalid chain: <chain> |
| Chain not supported for subwallets | 400 | Unsupported chain for subwallets |
| Currency not supported on that chain | 400 | Unsupported currency for chain <chain> |
| Address not valid or network not supported | 400 | Message describing the problem |
| Wallet service unavailable | 503 | Wallet service is temporarily unavailable. Please try again. |
Authorizations
Signed (HMAC) authentication. Required headers: x-access-id, x-request-id (UUID v4), x-timestamp (ISO 8601, must be within 5 minutes of server time), and authorization: the Base64 HMAC-SHA256 of the JSON string {"timeStamp":"","requestId":"","accessId":""} (keys in that order, no whitespace) using your access secret. The request body, method and path are not signed. The API key must be linked to an outlet.
Headers
Base64-encoded HMAC-SHA256 signature of {"timeStamp":"","requestId":"","accessId":""}, signed with your access secret. The request body is not part of the signature.
ISO 8601 timestamp; must be within 5 minutes of server time
A unique UUID v4 per request
Path Parameters
Blockchain address.
Query Parameters
ethereum, tron, bitcoin Currency symbol, case-insensitive. Omit for all balances.