Skip to content

POST /apiv2/usdt/analyze

Calculate TRON USDT transfer cost (private endpoint — authenticated).

Returns the exact same TransferAnalysis payload as the public GET variant, but with a much higher rate limit (50 req/sec per Kong node instead of 1/sec) and with request data passed in a JSON body instead of the URL. Use this endpoint for any production integration.

Endpoint URL

POST https://netts.io/apiv2/usdt/analyze

Authentication

Either of the following two headers is accepted (both supported simultaneously; X-API-KEY is preferred because it matches the rest of the Netts /apiv2/* API surface):

HeaderRequiredDescription
Content-TypeYesMust be application/json.
X-API-KEYPreferredYour Netts API key — exactly the same format used for /apiv2/order1h and other authenticated Netts endpoints.
AuthorizationAccepted as an alternativeBearer {key} or just {key} (no prefix). Use this if your HTTP client has a built-in bearer/auth flow.

If both headers are sent, X-API-KEY wins.

IP whitelist: the IP from which the request reaches our edge must be in the whitelist configured for your API key (same mechanism as the other /apiv2/* endpoints). Requests from a non-whitelisted IP return 401 Unauthorized with "Invalid API key or IP not in whitelist".

Reusing your order1h headers

If you already call /apiv2/order1h with X-API-KEY: {key}, you can send the exact same X-API-KEY header to /apiv2/usdt/analyze — the calculator now recognises it as the primary authentication header.

Request body

json
{
    "sender_address":   "TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe",
    "receiver_address": "TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL"
}

Fields

FieldTypeRequiredConstraints
sender_addressstringYesValid TRON address — 34 chars, starts with T, valid base58 checksum.
receiver_addressstringYesValid TRON address; must differ from sender_address.

TIP

There is no amount field. The calculator returns the cost and resource requirements for a single USDT transfer between the two addresses; if you need the breakdown for a specific USDT amount, multiply the recommended energy by the transfer count on your side — a single TRC-20 USDT transfer consumes the same ~130 k energy regardless of amount.

Request examples

cURL (preferred — X-API-KEY)

bash
curl -X POST "https://netts.io/apiv2/usdt/analyze" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -d '{
        "sender_address":   "TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe",
        "receiver_address": "TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL"
      }'

cURL (alternative — Authorization)

bash
curl -X POST "https://netts.io/apiv2/usdt/analyze" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
        "sender_address":   "TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe",
        "receiver_address": "TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL"
      }'

Python

python
import requests

API_KEY = "YOUR_API_KEY"

payload = {
    "sender_address":   "TFLit1TFohBtT2f8UVCLFVPmZxawxqByYe",
    "receiver_address": "TTKR9aQdJWTgXLK9cmzaDitT5VXE497thL",
}

r = requests.post(
    "https://netts.io/apiv2/usdt/analyze",
    headers={
        "Content-Type": "application/json",
        "X-API-KEY":    API_KEY,           # preferred; same header as /apiv2/order1h
        # or, equivalently:
        # "Authorization": f"Bearer {API_KEY}",
    },
    json=payload,
    timeout=15,
)

if r.status_code == 200:
    data = r.json()["data"]
    print("Energy needed:", data["requirements"]["energy_with_buffer"])
    print("Total cost:   ", data["costs"]["total_cost_trx"], "TRX")
    print("Method:       ", data["costs"]["recommended_method"])
elif r.status_code == 401:
    print("Auth failed:", r.json())
elif r.status_code == 429:
    print("Rate-limited — Retry-After:", r.headers.get("Retry-After"))
else:
    print("Error:", r.status_code, r.json())

Response

Success (200 OK)

Identical envelope to the public endpoint:

json
{
    "status": "success",
    "data": { /* TransferAnalysis — see the public-endpoint page */ },
    "current_utc_time": "2026-04-23 11:54:13",
    "processing_time_ms": 20.14
}

The full field-by-field description of data is on the public-endpoint page — see TransferAnalysis, AddressInfo, Requirements and Costs.

Errors

Order of checks

Authentication is validated before body validation. If the Authorization header is missing/invalid or your IP is not whitelisted, you will always see 401 — even if the JSON body is also malformed. Fix auth first, then re-test with a valid key; only then will Pydantic body-validation errors (422) surface.

HTTPBodyWhen
401{"code": -1, "msg": "API key not provided (expected X-API-KEY or Authorization header)"}Neither X-API-KEY nor Authorization header present.
401{"code": -1, "msg": "Invalid API key or IP not in whitelist"}Unknown key, or request IP not in your whitelist.
404{"code": -1, "msg": "User not found"}Key valid but user record was not found (rare).
422{"detail": [{"loc": ["body","sender_address"], "msg": "Invalid TRON address length", "type": "value_error"}]}FastAPI/Pydantic body validation failed. Status is 422 Unprocessable Entity, not 400.
422{"detail": [{..., "msg": "Sender and receiver cannot be the same address", "type": "value_error"}]}sender_address == receiver_address.
429{"message": "API rate limit exceeded"}Sustained traffic beyond 50 req/sec on a Kong node.
500{"code": -1, "msg": "Internal server error"}Unexpected server-side failure.

Rate limit

  • 50 requests / second per Kong node (limit_by = ip, policy local).
  • minute / hour limits are not set — only the per-second limit applies.
  • Every response carries the standard Kong headers: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, X-RateLimit-Limit-Second, X-RateLimit-Remaining-Second, and Retry-After on a 429.

Example 429 response

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

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

TIP

If you are reaching 50 req/sec with a single API key and need more, contact support — the limit can be raised per key, or a dedicated rate-limit plugin can be attached to your consumer.

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 — this is the root cause of most cURL error 28 (Connection timed out) reports from integrators.

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 50 req/sec 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_address, receiver_address) pair — the underlying resource prices and on-chain state rarely change fast enough to warrant more frequent recalculation.

Browser / CORS support

This endpoint is designed for server-to-server integrations and currently does not support direct calls from a browser: the upstream FastAPI app advertises Access-Control-Allow-Methods: GET only, so the preflight OPTIONS for a cross-origin POST will fail in browsers.

If you need to call the calculator from a browser front-end, proxy the request through your own back-end (which holds the API key) instead of exposing the key to the client anyway.

TIP

If your use case legitimately requires browser-side POST with an API key (e.g. a trusted internal dashboard on a known origin), contact support — a CORS plugin can be attached at the Kong level for your route.

Notes

  • Response format is intentionally identical to the public endpoint, so the client code that parses the public response continues to work after you migrate to the authenticated variant — only the call itself changes.
  • Both X-API-KEY: {key} (preferred, consistent with /apiv2/order1h) and Authorization: Bearer {key} / Authorization: {key} are accepted; if both are sent, X-API-KEY wins.
  • Cloudflare / reverse-proxy interposition does not affect this endpoint the same way it affects the public one, because authenticated traffic is rate-limited per-Kong-node and per-consumer semantics can be enabled on request.