GET /apiv2/balances/
Lee los saldos de cualquier dirección TRON: ahora mismo, en un momento pasado, a lo largo del tiempo o sumados para un período. Seis endpoints, todos síncronos: la respuesta viene en la contestación, no hay cola ni nada que consultar periódicamente.
URL base del endpoint
https://netts.io/apiv2/balances/{address}{address} es una dirección TRON en base58, exactamente de 34 caracteres.
Encabezados de solicitud
| Header | Required | Description |
|---|---|---|
X-API-KEY | sí | Clave API del panel de control |
X-Real-IP | sí | Una dirección de la lista blanca de la clave |
El saldo de su cuenta debe ser de al menos 4 TRX. Una cuenta sin fondos es respondida con 402 antes de que la solicitud llegue a los datos.
Los seis endpoints
| Endpoint | Responde |
|---|---|
GET /apiv2/balances/{address} | cada token retenido ahora mismo |
GET /apiv2/balances/{address}/at?on=YYYY-MM-DD | saldos al final de esa fecha, UTC |
GET /apiv2/balances/{address}/at-block?block=N | saldos en un bloque exacto, o en ts=YYYY-MM-DD HH:MM:SS |
GET /apiv2/balances/{address}/history?token_id=TRX&days=90 | cómo se movió un token, día a día |
GET /apiv2/balances/{address}/summary?date_from=&date_to= | apertura, entradas, salidas, tarifas y cierre por token |
GET /apiv2/balances/{address}/statement?date_from=&date_to= | vista previa del extracto con operaciones individuales |
Ejemplos
curl -s 'https://netts.io/apiv2/balances/TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
-H 'X-API-KEY: your-api-key' \
-H 'X-Real-IP: 203.0.113.10'{
"status": "success",
"code": 0,
"msg": "",
"data": {
"address": "TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"as_of_block": 86012345,
"live": false,
"hide_spam": false,
"total_value_usd": "385.25",
"balances": [
{
"token_id": "TRX",
"symbol": "TRON",
"token_type": "TRX",
"decimals": 6,
"balance": "1141.899000",
"price_usd": "0.334968",
"value_usd": "382.50",
"is_verified": true,
"is_spam": false,
"balance_source": "events",
"node_balance": "1141.899000"
}
]
}
}Cosas que vale la pena saber antes de integrar
Las cantidades son cadenas de texto, no números. "1141.899000" es un decimal serializado como texto para que no se pierda precisión en un viaje de ida y vuelta de punto flotante. Analícelo con un tipo decimal, no con un float.
En una respuesta sobre el pasado, balance es la respuesta y node_balance no lo es. balance es la cantidad en el momento por el que preguntó. node_balance es lo que la cadena contiene ahora mismo, en cada respuesta; por lo tanto, en una respuesta sobre el mes pasado todavía muestra el número de hoy. Nunca lo muestre como la cantidad histórica. Para una pregunta sobre el ahora, los roles se intercambian; esa es la siguiente sección.
Una fecha significa el final de ese día. ?on=2026-09-01 responde para 2026-09-01 23:59:59Z. Si necesita el inicio de un día, solicite el final del día anterior, o use /at-block con un ts explícito.
Dos saldos, y por qué "ahora" es el caso difícil
Una respuesta incluye dos números diferentes, y en una dirección activa no coinciden:
| Campo | Qué es | Cuándo es exacto |
|---|---|---|
balance | El valor del libro mayor, reconstruido a partir de eventos indexados de la cadena hasta el bloque reportado en as_of_block | Exacto para ese bloque, el cual no es el bloque más reciente |
node_balance | Lo que un nodo de TRON contiene ahora mismo | Siempre actual, nunca histórico |
balance no es "el saldo en la cadena ahora mismo". Es el saldo a partir de as_of_block. Cuando necesite el número actual de la cadena, lea node_balance; se toma de un nodo de TRON en el momento de la solicitud y, para TRX, mediante la fórmula completa: saldo líquido más frozenV2 en staking más lo que está delegado hacia afuera. En una dirección que contenía 41,7 millones de TRX en staking respondió 42035672.226020, que es exactamente 237799.226020 + 41760434 + 36816 + 623. Leer solo el campo simple balance del nodo habría mostrado 237 mil y se habría equivocado por dos órdenes de magnitud.
Pero node_balance no se completa para cada fila. TRX y cada TRC10 se devuelven en una sola llamada a getaccount, por lo que siempre lo incluyen. TRC20 no puede: un nodo no tiene forma de listar los tokens TRC20 que posee una dirección, por lo que balanceOf solo se solicita para los principales. Medido en una billetera con 504 filas TRC20, 494 de ellas devolvieron null. Ese null es por política y no un fallo, y el mismo null aparece si el nodo no está disponible brevemente. Así que para TRX y TRC10 el valor actual de la cadena siempre está disponible para usted; para un TRC20 de cola larga, todo lo que tiene es balance y el bloque en el que se basa.
El libro mayor avanza a un bloque solo una vez que cada escritor de indexación ha confirmado ese bloque, y su marca de agua es el mínimo entre todos ellos. Los escritores más lentos publican sus marcas por lotes, por lo que la brecha se amplía de manera constante y luego retrocede de golpe: un diente de sierra, no una constante.
Muestreado en una ventana de 20 minutos el 6 de septiembre de 2026:
| Bloques por detrás de la cabeza | Tiempo por detrás | |
|---|---|---|
| Mejor | 22 | ~1 min |
| Mediana | 44 | ~2 min |
| Percentil 90 | 86 | ~4 min |
| Peor observado | 121 | ~6 min |
Planifique asumiendo que el libro mayor estará unos minutos por detrás de la cadena, no unos segundos.
Lo que se deduce de esto:
- Una dirección inactiva es exacta incluso para el "ahora". Una vez que nada se ha movido durante más tiempo que el retraso actual, el libro mayor se ha puesto al día y
balancees igual anode_balance. - En una dirección que acaba de realizar transacciones,
balancepuede ser erróneo en cualquier dirección: demasiado bajo mientras una transferencia entrante aún no esté indexada, demasiado alto mientras lo esté una saliente. live=truereduce la brecha sin cerrarla. Aplica sobre la marcha la cola de eventos de transferencia entreas_of_blocky la cabeza de la cadena, durante 30–80 ms. No mueveas_of_block, no tiene en cuenta las tarifas y omite deliberadamente los tokens TRC10, que son rastreados por un índice independiente. Un ejemplo medido: una dirección cuyo libro mayor reportaba157.317444TRX respondió766.194807conlive=true, mientras que el nodo contenía1698.995472. Es útil, peronode_balancesigue siendo el único campo que refleja el valor actual de la cadena.- Las respuestas históricas son exactas, sin excepciones.
/at,/at-block,/history,/summaryy/statementdescriben puntos por los que el libro mayor pasó hace mucho tiempo. No hay ningún retraso que compensar.
Para contabilidad, conciliación y extractos, use los endpoints históricos y confíe en ellos. Para una pantalla de billetera en tiempo real, muestre node_balance donde esté presente —lo que cubre TRX y cada TRC10— y recurra a balance con as_of_block a su lado donde sea null, para que el lector sepa en qué bloque se basa el número.
/history devuelve solo los días que tuvieron actividad. Solicitar days=7 en una dirección que tuvo movimientos en tres de ellos devuelve tres puntos, no siete. Cada punto contiene el balance de cierre de ese día y el delta respecto al punto anterior.
/summary se concilia por sí mismo. Para cada token opening_balance + period_in − period_out − period_fees = closing_balance, y el motor devuelve esa aritmética ya desglosada en control_formula, por ejemplo 76493.940406 + 141490.950160 - 216763.731366 - 79.260200 = 1141.899000. Las tarifas se desglosan en period_fees_energy y period_fees_bandwidth. Tenga en cuenta que /summary puede informar un pequeño saldo negativo para un token que el endpoint de saldo actual omite por completo.
/statement está limitado por ops_limit. Acepta de 10 a 5000 operaciones; cualquier valor fuera de ese rango es un 422. operations_total es el recuento real para el período y operations_truncated indica si la lista fue cortada. token_id tiene como valor predeterminado TRX cuando se omite. Para obtener un extracto completo de más de 5000 operaciones, solicite un archivo en su lugar; consulte Archivos de extractos.
El orden de los tokens es intencionado. TRX y las principales monedas estables van primero, luego los tokens verificados que tienen un precio, y después todo lo demás. No vuelva a ordenar por cantidad: el spam distribuido por airdrop a menudo contiene enormes saldos nominales y subiría a la parte superior.
El spam se marca, no se elimina. is_spam señala los tokens clasificados como engañosos. Pase hide_spam=true para excluirlos de la respuesta; TRX y USDT nunca se ocultan.
Límites de tasa
Cada endpoint acepta 10 solicitudes por segundo, compartidas entre todos los clientes de ese endpoint. El límite es por endpoint, por lo que /history y /summary no compiten entre sí.
Superarlo genera un 429 con Retry-After: 1, junto con RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset. Reintente después del retraso indicado.
Un segundo límite mucho más amplio de 100 solicitudes por segundo por IP de origen se aplica a toda la API. Los dos se distinguen por el mensaje: el límite del endpoint dice Endpoint rate limit exceeded (10 req/s shared), el de toda la cuenta dice API rate limit exceeded.
Respuestas de error
| HTTP | Significado |
|---|---|
400 | la dirección tiene 34 caracteres pero falla en su suma de comprobación base58 |
401 | clave faltante o no válida, o la IP de origen no está en la lista blanca |
402 | saldo de cuenta por debajo del mínimo de 4 TRX |
403 | la clave API está bloqueada; póngase en contacto con soporte |
422 | falta un parámetro o está fuera de rango: una longitud de dirección incorrecta, o un ops_limit fuera de 10–5000 |
429 | límite de velocidad excedido |
503 | el motor de saldos no respondió; la solicitud no fue contabilizada, reintente |
Los cuerpos de error vienen en tres formatos, dependiendo de qué capa rechazó la solicitud. Realice la coincidencia basándose en el estado HTTP, no en el cuerpo.
// 401, 402, 403 — the gateway, before the request reaches the service
{"detail": {"code": 1004, "msg": "Insufficient funds. Minimum balance is 4 TRX. Please top up your account."}}
// 400, 422 — the service, after parameters are parsed
{"status": "error", "code": -4, "msg": "address must be base58 (T...)", "data": {"code": -4, "msg": "address must be base58 (T...)"}}
// 429 — the rate limiter
{"message": "Endpoint rate limit exceeded (10 req/s shared), retry shortly", "request_id": "e5dbf25437d2eb215c764617d50b8d3b"}Relacionado
- Archivos de extractos — el extracto completo como un archivo CSV o PDF
- Webhooks de informes — recibir una notificación cuando un archivo esté listo