Skip to content

GET /apiv2/usdt/{sender}&

Calculate TRON USDT transfer cost (public endpoint, no API key required).

Returns a detailed analysis of the sender and receiver accounts, resource requirements (energy/bandwidth) and recommended cost path.

Low rate limit — intended for occasional / testing use

This endpoint is shared globally and rate-limited at 1 req/sec and 60 req/min. When your application is behind Cloudflare or another reverse proxy, the limit may effectively be shared between all clients reaching Netts through the same edge, so you may see 429 Too Many Requests sooner than 60 requests/minute from a single user.

For anything beyond sporadic calls, use the authenticated POST /apiv2/usdt/analyze endpoint — it has a much higher per-key limit (50 req/sec).

Endpoint URL

GET https://netts.io/apiv2/usdt/{sender}&{receiver}

URL parameters

ParameterTypeRequiredDescription
senderstringYesTRON address of the sender
receiverstringYesTRON address of the receiver

Addresses are passed in the path, separated by an ampersand (&). Both must be valid base58 TRON addresses (34 characters, start with T, valid checksum).

Request examples

cURL

bash
curl "https://netts.io/apiv2/usdt/TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe&TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL"

Python

python
import requests

sender   = "TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe"
receiver = "TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL"

url = f"https://netts.io/apiv2/usdt/{sender}&{receiver}"
response = requests.get(url, timeout=15)

if response.status_code == 200:
    payload = response.json()
    data = payload["data"]
    print(f"Can transfer:        {data['can_transfer']}")
    print(f"Energy needed:       {data['requirements']['energy_needed']}")
    print(f"Bandwidth needed:    {data['requirements']['bandwidth_needed']}")
    print(f"Total cost (TRX):    {data['costs']['total_cost_trx']}")
    print(f"Recommended method:  {data['costs']['recommended_method']}")
elif response.status_code == 429:
    print("Rate-limited — retry after:", response.headers.get("Retry-After"), "s")
else:
    print("Error:", response.json())

Response

Success (200 OK)

Top-level envelope:

json
{
    "status": "success",
    "data": { /* TransferAnalysis — see below */ },
    "current_utc_time": "2026-04-23 11:54:13",
    "processing_time_ms": 19.27
}

data (TransferAnalysis)

FieldTypeDescription
senderAddressInfoFull account info for the sender (balance, staking, delegation, activation).
receiverAddressInfoFull account info for the receiver.
requirementsRequirementsEnergy / bandwidth the transfer will need (raw + with safety buffer).
costsCostsBurn vs. rent cost breakdown and the recommended method.
can_transferbooleantrue if the transfer can be executed with current resources/prices.
issuesstring[]Concerns detected during analysis (e.g. insufficient bandwidth).
recommendationsstring[]Human-readable suggestions for the client.
variation_idstring | nullMatched scenario ID (e.g. "CUSTOM") from the internal variations catalogue.
AddressInfo

Typical fields you will use in integrations: address, is_activated, trx_balance, usdt_balance, has_usdt, energy_balance, bandwidth_balance. Additional low-level fields for advanced use: trx_balance_sun, energy_total, bandwidth_total, bandwidth_free, bandwidth_staked, energy_used, bandwidth_used, create_time, latest_operation_time, staked_for_energy, staked_for_bandwidth, delegated_for_energy, delegated_for_bandwidth, delegated_out_energy, delegated_out_bandwidth, votes.

Requirements
FieldTypeDescription
energy_neededintRaw energy units required for the transfer.
bandwidth_neededintRaw bandwidth units required.
energy_with_bufferintEnergy rounded up to a safe rental tier (e.g. 131 000).
bandwidth_with_bufferintBandwidth with a small safety buffer.
receiver_has_usdtbooleanWhether the receiver already holds USDT (affects energy).
Costs
FieldTypeDescription
energy_burn_trxdecimalTRX burned if energy is paid via direct burn.
bandwidth_burn_trxdecimalTRX burned to cover bandwidth if it is not available for free.
total_burn_trxdecimalenergy_burn_trx + bandwidth_burn_trx.
total_burn_suninttotal_burn_trx expressed in SUN (10⁻⁶ TRX).
energy_rental_trxdecimalCost to rent the required energy from Netts for the period below.
energy_rental_sunintSame as above but in SUN.
rental_time_periodstringe.g. "1h", "5m", or "not_needed" when rental is not the best path.
rental_price_per_unitintRental price per energy unit in SUN for the chosen period.
savings_trxdecimalHow much cheaper rent is vs. burn (can be negative if burn is best).
savings_percentagefloatSame as a percentage.
recommended_methodstring"burn" or "rent" — the cheaper option for the current request.
total_cost_trxdecimal | nullActual cost if you follow recommended_method.
sender_activation_costdecimal | nullExtra cost if the sender account needs activation, else null.

Example real response (abbreviated)

json
{
    "status": "success",
    "data": {
        "sender":   { "address": "TFLit1...", "is_activated": true,  "trx_balance": 191.943, "usdt_balance": 24410.499, "energy_balance": 195297, "bandwidth_balance": 148, "has_usdt": true,  "...": "..." },
        "receiver": { "address": "TTKR9a...", "is_activated": true,  "trx_balance":  18.656, "usdt_balance":     0.0,   "energy_balance":      0, "bandwidth_balance": 263, "has_usdt": false, "...": "..." },
        "requirements": {
            "energy_needed": 130285,
            "bandwidth_needed": 345,
            "energy_with_buffer": 131000,
            "bandwidth_with_buffer": 360,
            "receiver_has_usdt": false
        },
        "costs": {
            "energy_burn_trx": 0.0,
            "bandwidth_burn_trx": 0.345,
            "total_burn_trx": 0.345,
            "total_burn_sun": 345000,
            "energy_rental_trx": 0.0,
            "energy_rental_sun": 0,
            "rental_time_period": "not_needed",
            "rental_price_per_unit": 0,
            "savings_trx": 0.0,
            "savings_percentage": 0.0,
            "recommended_method": "burn",
            "total_cost_trx": 0.345,
            "sender_activation_cost": null
        },
        "can_transfer": true,
        "issues": [
            "Insufficient bandwidth: have 148, need 345. Network will burn 0.345 TRX for full amount"
        ],
        "recommendations": [
            "Insufficient bandwidth: have 148, need 345. Full amount of 0.345 TRX will be burned",
            "💰 Total cost: 0.345 TRX (burn for all resources)"
        ],
        "variation_id": "CUSTOM"
    },
    "current_utc_time": "2026-04-23 11:54:13",
    "processing_time_ms": 19.27
}

Errors

HTTPBody (example)When
400{"code": -1, "msg": "Invalid sender address format: Txyz..."}Address fails TRON base58 / length / checksum validation.
400{"code": -1, "msg": "Expected at least 2 parameters: sender&receiver"}URL does not contain two addresses separated by &.
400{"code": -1, "msg": "Sender and receiver cannot be the same address"}Sender and receiver addresses are identical.
429{"message": "API rate limit exceeded"}Rate limit exceeded (see the warning at the top of this page).
500{"code": -1, "msg": "Internal server error"}Unexpected server-side failure.

Rate-limit headers

On every response (including 429) the following headers are returned:

HeaderMeaning
X-RateLimit-Limit-SecondMaximum requests allowed per second (currently 1).
X-RateLimit-Remaining-SecondHow many you may still send this second.
X-RateLimit-Limit-MinuteMaximum requests allowed per minute (currently 60).
X-RateLimit-Remaining-MinuteHow many you may still send this minute.
Retry-AfterOn a 429 — seconds to wait before retrying.

Debug headers

Every response also carries identifiers useful when opening a support ticket — please include them verbatim so we can find the request in our logs within seconds:

HeaderMeaning
X-Request-IDApplication-side request ID (generated by the calculator).
X-Process-TimeApplication processing time in milliseconds (upstream, excluding Kong).
X-Kong-Request-IdKong-side request ID (present in Kong access logs).

Client-side timeout and retry

The calculator performs live on-chain queries to TRON nodes for each request, so under load or slow upstream nodes a single call can take several seconds. Short client timeouts will fail even on healthy responses.

Recommended settings:

  • Timeout ≥ 15 seconds (30 s is safer). The default 10 s used by many HTTP clients is too short.
  • On HTTP 429, honour the Retry-After header (seconds). Add small jitter (e.g. 0–200 ms) before retrying, then use exponential backoff if you still hit the limit.
  • On HTTP 5xx or network errors, retry at most 2–3 times with exponential backoff; do not hammer the endpoint.
  • Cache the result client-side for 30–60 seconds per (sender, receiver) pair — the underlying resource prices and on-chain state rarely change fast enough to warrant more frequent recalculation.

Example 429 response

http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
RateLimit-Limit: 1
RateLimit-Remaining: 0
RateLimit-Reset: 1
Retry-After: 1
X-RateLimit-Limit-Second: 1
X-RateLimit-Remaining-Second: 0
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 0

{"message":"API rate limit exceeded"}

Notes

  • Anonymous access: no X-API-KEY, no Authorization header, no IP whitelist.
  • The response is always wrapped in {status, data, current_utc_time, processing_time_ms} — integrations should read pricing from data.costs and requirements from data.requirements.
  • The response is computed in real time — it reflects the current TRON resource prices from Netts and the current on-chain state of both addresses, so expect small variations between consecutive calls.
  • If your application needs to call the calculator more than a few times per minute (per-IP / per-CF-edge), switch to POST /apiv2/usdt/analyze with your API key.