Chain — API reference
Read-only TRON helpers.
| Method | Path | Summary |
|---|---|---|
GET | /v1/resources/{address} | Resource situation of an address |
GET | /v1/status | Service status |
POST | /v1/estimate/transfer | Energy needed for a TRC-20 transfer |
Generated from openapi.yaml at build time. 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 | ||
bandwidth.used | integer | ||
bandwidth.available | integer | ||
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":1600,"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"
}
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.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 USDT (TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t)
when contract_address is omitted.
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 USDT TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t. | |
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: 5m, 15m, 1h, 1d, 3d, 30d | 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. |
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: 5m, 15m, 1h, 1d, 3d, 30d | Rental period. The API sells 5m and 1h; 1d exists but is switched off. 15m, 3d and 30d are retired and never sold — they stay in the enum only so old orders parse. 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"
}