Appearance
GET /apiv2/balances/
Consulte os saldos de qualquer endereço TRON: agora, em um momento passado, ao longo do tempo ou consolidados para um período. Seis endpoints, todos síncronos — a resposta vem no retorno, não há fila nem nada para consultar via polling.
URL base do endpoint
https://netts.io/apiv2/balances/{address}{address} é um endereço TRON em base58, exatamente com 34 caracteres.
Cabeçalhos da requisição
| Header | Required | Description |
|---|---|---|
X-API-KEY | sim | Chave de API do painel |
X-Real-IP | sim | Um endereço da lista de permissões da chave |
O saldo da sua conta deve ser de pelo menos 4 TRX. Uma conta sem saldo recebe 402 antes que a requisição chegue aos dados.
Os seis endpoints
| Endpoint | Responde |
|---|---|
GET /apiv2/balances/{address} | todos os tokens mantidos agora |
GET /apiv2/balances/{address}/at?on=YYYY-MM-DD | saldos no final dessa data, UTC |
GET /apiv2/balances/{address}/at-block?block=N | saldos em um bloco exato, ou em ts=YYYY-MM-DD HH:MM:SS |
GET /apiv2/balances/{address}/history?token_id=TRX&days=90 | como um token se movimentou, dia a dia |
GET /apiv2/balances/{address}/summary?date_from=&date_to= | abertura, entrada, saída, taxas e fechamento por token |
GET /apiv2/balances/{address}/statement?date_from=&date_to= | pré-visualização do extrato com operações individuais |
Exemplos
bash
curl -s 'https://netts.io/apiv2/balances/TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
-H 'X-API-KEY: your-api-key' \
-H 'X-Real-IP: 203.0.113.10'json
{
"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"
}
]
}
}O que vale a pena saber antes de integrar
Os valores são strings, não números. "1141.899000" é um decimal serializado como texto para que nenhuma precisão seja perdida em conversões de ponto flutuante. Faça o parsing com um tipo decimal, não float.
Em uma resposta sobre o passado, balance é a resposta e node_balance não é. balance é o montante no ponto sobre o qual você perguntou. node_balance é o que a blockchain contém agora, em cada resposta — então, em uma resposta sobre o mês passado, ele ainda mostra o número de hoje. Nunca o exiba como o valor histórico. Para uma consulta sobre o agora, os papéis se invertem; essa é a próxima seção.
Uma data significa o fim daquele dia. ?on=2026-09-01 responde para 2026-09-01 23:59:59Z. Se você precisar do início de um dia, solicite o final do dia anterior ou use /at-block com um ts explícito.
Dois saldos, e por que o "agora" é a parte complexa
Uma resposta traz dois números diferentes e, em um endereço ativo, eles não coincidem:
| Campo | O que é | Quando é exato |
|---|---|---|
balance | O valor do livro-razão, reconstruído a partir de eventos indexados da blockchain até o bloco informado em as_of_block | Exato para aquele bloco — que não é o bloco mais recente |
node_balance | O que um nó da TRON contém agora | Sempre atual, nunca histórico |
balance não é "o saldo na blockchain agora". É o saldo a partir de as_of_block. Quando você precisar do número atual da blockchain, leia node_balance — ele é obtido de um nó da TRON no momento da requisição e, para TRX, pela fórmula completa: saldo líquido mais frozenV2 em stake mais o que está delegado para fora. Em um endereço contendo 41,7 milhões de TRX em stake, a resposta foi 42035672.226020, que é exatamente 237799.226020 + 41760434 + 36816 + 623. Ler apenas o campo simples balance do nó teria mostrado 237 mil e errado por duas ordens de grandeza.
Mas node_balance não é preenchido para todas as linhas. TRX e cada TRC10 retornam em uma única chamada getaccount, por isso sempre o contêm. TRC20 não consegue: um nó não tem como listar os tokens TRC20 que um endereço possui, portanto balanceOf é consultado apenas para os principais. Medido em uma carteira com 504 linhas TRC20, 494 delas retornaram null. Esse null é uma política e não uma falha, e o mesmo null aparece se o nó estiver brevemente inacessível. Portanto, para TRX e TRC10 o valor atual da blockchain está sempre disponível para você; para um TRC20 de cauda longa, tudo o que você tem é balance e o bloco no qual ele se baseia.
O livro-razão só avança para um bloco depois que cada escritor de indexação tiver confirmado esse bloco, e sua marca de corte é o mínimo entre todos eles. Os escritores mais lentos publicam suas marcas em lotes, então a defasagem aumenta gradualmente e depois é corrigida de uma vez — um padrão dente de serra, não uma constante.
Amostrado em uma janela de 20 minutos em 6 de setembro de 2026:
| Blocos atrás da ponta | Tempo de atraso | |
|---|---|---|
| Melhor | 22 | ~1 min |
| Mediana | 44 | ~2 min |
| Percentil 90 | 86 | ~4 min |
| Pior observado | 121 | ~6 min |
Planeje considerando que o livro-razão estará alguns minutos atrás da blockchain, não alguns segundos.
O que decorre disso:
- Um endereço inativo é exato até mesmo para o "agora". Assim que nada se movimentar por um período maior que a defasagem atual, o livro-razão terá alcançado o estado atual e
balanceserá igual anode_balance. - Em um endereço que acabou de transacionar,
balancepode estar incorreto em qualquer direção — muito baixo enquanto uma transferência recebida ainda não estiver indexada, muito alto enquanto uma enviada não estiver. live=truereduz a defasagem sem eliminá-la. Ele aplica a parte final dos eventos de transferência entreas_of_blocke a ponta da cadeia em tempo de execução, levando de 30 a 80 ms. Ele não move oas_of_block, não calcula taxas e ignora deliberadamente tokens TRC10, que são rastreados por um índice separado. Um exemplo medido: um endereço cujo livro-razão reportava157.317444TRX respondeu766.194807comlive=true, enquanto o nó continha1698.995472. Útil, masnode_balancecontinua sendo o único campo que reflete o valor atual da blockchain.- Respostas históricas são exatas, ponto final.
/at,/at-block,/history,/summarye/statementdescrevem pontos pelos quais o livro-razão já passou há muito tempo. Não há atraso a considerar.
Para contabilidade, conciliação e extratos, use os endpoints históricos e confie neles. Para uma tela de carteira em tempo real, exiba node_balance onde ele estiver presente — o que cobre TRX e todo TRC10 — e use balance como alternativa com as_of_block ao lado onde for null, para que o leitor saiba em qual bloco o número se baseia.
/history retorna apenas os dias em que houve atividade. Pedir days=7 em um endereço que teve movimentação em três deles retorna três pontos, não sete. Cada ponto traz o balance de fechamento daquele dia e o delta em relação ao ponto anterior.
/summary se reconcilia sozinho. Para cada token, opening_balance + period_in − period_out − period_fees = closing_balance, e o mecanismo retorna essa aritmética já detalhada em control_formula, por exemplo 76493.940406 + 141490.950160 - 216763.731366 - 79.260200 = 1141.899000. As taxas são discriminadas em period_fees_energy e period_fees_bandwidth. Observe que /summary pode reportar um pequeno saldo negativo para um token que o endpoint de saldo atual omite completamente.
/statement é limitado por ops_limit. Ele aceita de 10 a 5000 operações; qualquer valor fora desse intervalo resulta em 422. operations_total é a contagem real para o período e operations_truncated informa se a lista foi truncada. token_id tem como padrão TRX quando omitido. Para um extrato completo com mais de 5000 operações, solicite um arquivo — consulte Arquivos de extrato.
A ordem dos tokens é deliberada. TRX e as principais stablecoins vêm primeiro, depois os tokens verificados que possuem preço e, em seguida, todo o restante. Não reordene pelo montante: spans distribuídos via airdrop frequentemente trazem saldos nominais enormes e ficariam no topo.
Spam é sinalizado, não removido. is_spam sinaliza tokens classificados como enganosos. Envie hide_spam=true para removê-los da resposta; TRX e USDT nunca são ocultados.
Limites de taxa
Cada endpoint aceita 10 requisições por segundo, compartilhadas entre todos os clientes desse endpoint. O limite é por endpoint, portanto /history e /summary não concorrem entre si.
Ultrapassá-lo retorna 429 com Retry-After: 1, acompanhado de RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset. Tente novamente após o atraso indicado.
Um segundo limite, muito mais amplo, de 100 requisições por segundo por IP de origem é aplicado em toda a API. Os dois se diferenciam pela mensagem: o limite do endpoint informa Endpoint rate limit exceeded (10 req/s shared), enquanto o da conta inteira informa API rate limit exceeded.
Respostas de erro
| HTTP | Significado |
|---|---|
400 | o endereço tem 34 caracteres, mas falha no checksum base58 |
401 | chave ausente ou inválida, ou o IP de origem não está na lista de permissões |
402 | saldo da conta abaixo do mínimo de 4 TRX |
403 | a chave de API está bloqueada; contate o suporte |
422 | um parâmetro está ausente ou fora do intervalo — comprimento incorreto de endereço ou um ops_limit fora de 10–5000 |
429 | limite de requisições excedido |
503 | o mecanismo de saldos não respondeu; a requisição não foi contabilizada, tente novamente |
Os corpos dos erros aparecem em três formatos, dependendo de qual camada rejeitou a requisição. Faça a validação pelo status HTTP, não pelo corpo.
json
// 401, 402, 403 — o gateway, antes de a requisição atingir o serviço
{"detail": {"code": 1004, "msg": "Insufficient funds. Minimum balance is 4 TRX. Please top up your account."}}
// 400, 422 — o serviço, após o parsing dos parâmetros
{"status": "error", "code": -4, "msg": "address must be base58 (T...)", "data": {"code": -4, "msg": "address must be base58 (T...)"}}
// 429 — o limitador de taxa
{"message": "Endpoint rate limit exceeded (10 req/s shared), retry shortly", "request_id": "e5dbf25437d2eb215c764617d50b8d3b"}Relacionados
- Arquivos de extrato — o extrato completo como arquivo CSV ou PDF
- Webhooks de relatórios — ser notificado quando um arquivo estiver pronto