Chain — API reference
Read-only TRON helpers.
| Method | Path | Summary |
|---|---|---|
GET | /v1/resources/{address} | Resource situation of an address |
GET | /v1/resources/{address}/usage | Energy and bandwidth an address used and burned |
GET | /v1/status | Service status |
POST | /v1/estimate/transfer | Energy needed for a TRC-20 transfer |
Base URL https://api.tenergy.me/v1, or https://api-nile.tenergy.me/v1 on Nile (Environments). Every request below is signed as in Authentication unless its Auth line says otherwise.
Resource situation of an address
GET /v1/resources/{address} · getAddressResources
Auth: Public — no credentials needed; a request signed with an API key (HMAC) is accepted too.
What the chain currently says about an address: whether it is activated, how much free energy and bandwidth it has, how much is delegated to it and by whom, and which of those delegations came from us.
Read from our own node with a short cache (as_of tells you how fresh it is). Use it to
decide whether an order is needed at all — the cheapest energy is the energy you do not buy.
Public. No credentials are needed; anonymous calls are limited per source IP and get
our_active_orders: []. A signed request lists that account’s own active orders on the
address and is counted against the key’s budget.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | yes |
Responses
| Status | Meaning |
|---|---|
200 | OK |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | Missing, malformed or rejected credentials. |
429 | Too many requests. |
500 | Something broke on our side. |
503 | Temporarily unable to serve. On order creation this is fail-secure: nothing was stored and nothing was charged, so retrying verbatim with the same client_order_id is safe. |
Response fields (AddressResources)
| Field | Type | Required | Description |
|---|---|---|---|
address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
activated | boolean | yes | False for an address that has never received anything on chain. |
balance_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
holds_usdt | boolean | null | Whether the address holds a non-zero USDT (TRC-20) balance — balanceOf > 0 on the network’s USDT contract. A USDT transfer TO an address that holds none writes a new storage slot and costs about twice the energy (~131k instead of ~65k). null when the read failed; the rest of the response is unaffected. | |
energy | object | yes | |
energy.limit | integer | Total energy the address may use. | |
energy.used | integer | ||
energy.available | integer | limit - used. What a transfer can spend now. | |
energy.delegated_in | integer | Part of the limit that came from delegations. | |
bandwidth | object | yes | |
bandwidth.limit | integer | Staked (delegated in included) plus the daily free allowance. | |
bandwidth.used | integer | ||
bandwidth.available | integer | What ONE transaction can use without burning TRX: the larger of what is left of the staked bandwidth and of the daily free bandwidth. The network charges a transaction to one of the two, never to both added up; when neither covers it, the transaction burns TRX for all of its bytes. | |
bandwidth.delegated_in | integer | ||
bandwidth.free_net_limit | integer | The daily free bandwidth allowance, included in limit. | |
our_active_orders | array of object | This account’s own currently-active orders delivering to this address. Delegations from other providers or other accounts are counted in delegated_in but are not listed — we cannot attribute them. | |
our_active_orders[].order_id | string | ||
our_active_orders[].amount | integer | ||
our_active_orders[].resource | enum: energy, bandwidth, activation | energy — TRON energy, the resource a TRC-20 transfer consumes. · bandwidth — TRON bandwidth (net), consumed by transaction size. · activation — one-off account activation; amount and tier do not apply. | |
our_active_orders[].expires_at | string (date-time) | ||
as_of | string (date-time) | yes | When this was read from the chain. Cached for a few seconds. |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"activated": true,
"balance_sun": 4120000,
"holds_usdt": true,
"energy": {"limit":131000,"used":0,"available":131000,"delegated_in":131000},
"bandwidth": {"limit":1600,"used":0,"available":1000,"delegated_in":0,"free_net_limit":600},
"our_active_orders": [
{
"order_id": "ord_01J9Z5P8T3WQ",
"amount": 65000,
"resource": "energy",
"expires_at": "2026-09-11T19:04:07.900Z"
}
],
"as_of": "2026-09-11T18:40:00.000Z"
}
Energy and bandwidth an address used and burned
GET /v1/resources/{address}/usage · getAddressUsage
Auth: Public — no credentials needed; a request signed with an API key (HMAC) is accepted too.
The transactions this address sent (and paid for) over the last 7 or 30 UTC days, today included: how much energy they used, how much TRX they burned for energy and for bandwidth, and the same per day. It answers “how much energy do I need, and what does burning cost me now” from the address’s own history.
Read from TronGrid’s indexed API and cached for 5 minutes per address and period. At most 2,000
transactions are read; capped: true means there were more and the totals are a lower bound.
Public. No credentials are needed; calls are limited per source IP, and fresh reads are also limited
per server, so a burst can answer 429 with retry_after.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | yes | |
days | query | enum: 7, 30 |
Responses
| Status | Meaning |
|---|---|
200 | OK |
400 | Malformed request — bad JSON, unknown field, wrong type. |
429 | Too many requests. |
500 | Something broke on our side. |
503 | Temporarily unable to serve. On order creation this is fail-secure: nothing was stored and nothing was charged, so retrying verbatim with the same client_order_id is safe. |
Response fields (AddressUsage)
| Field | Type | Required | Description |
|---|---|---|---|
address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
days | enum: 7, 30 | yes | |
transactions | integer | yes | Transactions the address sent in the period. |
usdt_transfers | integer | yes | Of those |
usdt_to_new | integer | Completed USDT transfers that went to an address holding no USDT. Classified by the energy the chain charged for the transfer (at least 100,000, the ~131k case); no balance is read per receiver. | |
usdt_to_existing | integer | Completed USDT transfers that went to an address already holding USDT (below 100,000 energy, the ~65k case). | |
out_of_energy | integer | yes | Of those |
energy_used | integer | yes | Energy consumed in total: own stake, delegated (rented) and burned. |
energy_burned_sun | integer | yes | SUN burned because energy was missing. |
bandwidth_burned_sun | integer | yes | SUN burned because bandwidth was missing. |
capped | boolean | yes | More than 2 |
per_day | array of object | yes | One entry per UTC day, oldest first; the last one is today so far. |
per_day[].date | string (date) | yes | |
per_day[].transactions | integer | yes | |
per_day[].energy_used | integer | yes | |
per_day[].energy_burned_sun | integer | yes | |
per_day[].bandwidth_burned_sun | integer | yes | |
per_day[].usdt_transfers | integer | Calls to the network’s USDT contract that day. | |
per_day[].usdt_to_new | integer | That day’s completed USDT transfers to a new holder. | |
per_day[].usdt_to_existing | integer | That day’s completed USDT transfers to an existing holder. | |
as_of | string (date-time) | yes |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"days": 7,
"transactions": 2,
"usdt_transfers": 2,
"out_of_energy": 0,
"energy_used": 130285,
"energy_burned_sun": 6514200,
"bandwidth_burned_sun": 345000,
"capped": false,
"per_day": [
{
"date": "2026-10-08",
"transactions": 2,
"energy_used": 130285,
"energy_burned_sun": 6514200,
"bandwidth_burned_sun": 345000
}
],
"as_of": "2026-10-09T10:00:00.000Z"
}
Service status
GET /v1/status · getStatus
Auth: Public.
Whether TEnergy is working right now, component by component: the database, incoming
payments (how long ago the payment scanner last advanced), energy delivery over the last
hour (orders, failures, median seconds from order to delegation) and energy available to
sell. status is the worst component. Delivery is judged only on an hour with at least 3
orders; a quiet hour is not an incident.
Public. No credentials are needed. The answer is cached for 10 seconds. It is 503 when
a component is down, so a plain HTTP check alerts without reading the body.
Responses
| Status | Meaning |
|---|---|
200 | Operational or degraded |
429 | Too many requests. |
503 | A component is down; the body has the same shape. |
Response fields (ServiceStatus)
| Field | Type | Required | Description |
|---|---|---|---|
status | enum: operational, degraded, down | yes | |
network | enum: mainnet, nile | yes | |
as_of | string (date-time) | yes | |
components | object | yes | |
components.api | object | yes | |
components.api.status | enum: operational, degraded, down | yes | |
components.database | object | yes | |
components.database.status | enum: operational, degraded, down | yes | |
components.redis | object | The cache that carries rate limits, idempotency and quote holds; down when it does not answer within 2 s (then requests fail too). | |
components.redis.status | enum: operational, degraded, down | yes | |
components.payments | object | yes | |
components.payments.status | enum: operational, degraded, down | yes | |
components.payments.scanner_updated_s_ago | integer | null | yes | Seconds since the payment scanner last advanced; null before its first block. |
components.delivery | object | yes | |
components.delivery.status | enum: operational, degraded, down | yes | |
components.delivery.orders_1h | integer | yes | |
components.delivery.failed_1h | integer | yes | |
components.delivery.median_delivery_s_1h | integer | null | yes | |
components.supply | object | yes | |
components.supply.status | enum: operational, degraded, down | yes | |
components.supply.available_energy | integer | yes | Energy that can be sold right now for 1 hour. |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"status": "operational",
"network": "mainnet",
"as_of": "2026-09-29T10:00:00.000Z",
"components": {
"api": {"status":"operational"},
"database": {"status":"operational"},
"payments": {"status":"operational","scanner_updated_s_ago":3},
"delivery": {"status":"operational","orders_1h":42,"failed_1h":0,"median_delivery_s_1h":6},
"supply": {"status":"operational","available_energy":18500000}
}
}
Energy needed for a TRC-20 transfer
POST /v1/estimate/transfer · estimateTransferEnergy
Auth: API key (HMAC).
How much energy a TRC-20 transfer from from_address to to_address will consume, and
what renting that much would cost. Defaults to the network’s USDT when contract_address
is omitted: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t on mainnet, TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf on Nile.
The number depends on whether the recipient already holds a non-zero balance of that
token — a first-time recipient costs roughly twice as much — which is why both addresses
are required. The estimate is produced by a triggerConstantContract simulation against
our node, so it reflects the current contract state, not a table.
Add a safety margin before ordering: the simulation is taken now and the transfer is
broadcast later, and the recipient’s balance may change in between. recommended_amount
already includes the platform’s margin and is the number to order.
Request body
JSON (TransferEstimateRequest), required.
| Field | Type | Required | Description |
|---|---|---|---|
from_address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
to_address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
contract_address | string | TRC-20 contract. Defaults to the network’s USDT (mainnet TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t, Nile TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf). | |
amount | string | null | Transfer amount in the token’s smallest unit, as a decimal string to avoid precision loss on large values. Affects the simulation only marginally; omit if unknown. | |
tier | enum (14 values) | Tier to price the rental at. Defaults to 1h. |
Example request body, from the contract (illustrative values):
{
"from_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"to_address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Responses
| Status | Meaning |
|---|---|
200 | OK |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | Missing, malformed or rejected credentials. |
429 | Too many requests. |
500 | Something broke on our side. |
503 | Temporarily unable to serve. On order creation this is fail-secure: nothing was stored and nothing was charged, so retrying verbatim with the same client_order_id is safe. |
Response fields (TransferEstimate)
| Field | Type | Required | Description |
|---|---|---|---|
from_address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
to_address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
contract_address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
recipient_holds_token | boolean | Whether the recipient already has a non-zero balance of this token. A first-time recipient roughly doubles the energy cost, which is the single biggest factor here. | |
energy_required | integer | yes | Energy the simulated transfer consumed — or, when estimate_basis is standard, the standard USDT figure (65,000 to a holder, 131,000 to a first-time recipient). |
estimate_basis | enum: simulation, standard | simulation: the node ran this exact transfer. standard: the sender cannot make it right now (no token balance, a frozen or blacklisted sender), so the node reverted the simulation and the standard USDT figures stand in. A transfer’s cost does not depend on the sender’s balance, so standard is still the right amount to order for a sender who will hold the token by the time they send. A node that cannot be reached is still 5003 chain_unavailable. | |
recommended_amount | integer | yes | What to actually order — energy_required plus a safety margin for state drift between this estimate and the broadcast. Order this, not energy_required. |
bandwidth_required | integer | ||
tier | enum (14 values, Tier) | Rental period, shortest first: minutes (5m–30m), hours (1h–12h) and days (1d–30d). Energy is sold for 5m, 10m, 15m, 30m, 1h and 1d; a term not on sale answers 2003 tier_unavailable. An order is filled by the cheapest provider term not shorter than the one asked (a 5m order may be bought as 15m); the order’s filled_tier says which term was bought. Check available on each GET /v1/prices row; a tier that is not available is rejected with 2003 tier_unavailable. | |
price_sun_per_unit | integer | ||
energy_amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
activate_amount_sun | integer (int64) | Activation fee for to_address when it is not yet activated. | |
total_amount_sun | integer (int64) | An amount in SUN (1 TRX = 1 000 000 SUN). Always an integer. | |
burn_alternative_sun | integer (int64) | What the same transfer would cost in burned TRX at the current network energy price, for comparison. Computed from the chain parameter (getEnergyFee), not from a stored constant. That parameter has been 100 SUN per energy since 2025-08-29; the example is 130,285 × 100. Any code or example still using 210 is reading a stale hard-coded constant. | |
as_of | string (date-time) | yes |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"from_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"to_address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"recipient_holds_token": false,
"energy_required": 130285,
"recommended_amount": 131000,
"bandwidth_required": 345,
"tier": "1h",
"price_sun_per_unit": 20,
"energy_amount_sun": 2620000,
"activate_amount_sun": 1200000,
"total_amount_sun": 3820000,
"burn_alternative_sun": 13028500,
"as_of": "2026-09-11T18:41:00.000Z"
}