Appearance
POST /apiv2/bandwidth
Alugue Bandwidth de TRON e delegue-a para um endereço destinatário por um período fixo (5 minutos ou 1 hora).
⚠️ Níveis de acesso.
- Contas credenciadas alugam qualquer quantidade (até 5000) dentro do tamanho do pool e dos limites máximos, com múltiplos pedidos simultâneos. O credenciamento é concedido pelo suporte da Netts.
- Sem credenciamento, você pode alugar 400 unidades uma vez — o próximo pedido só é permitido após o término do aluguel anterior. Pedidos para quantidades diferentes de 400, ou um segundo pedido enquanto o primeiro ainda estiver ativo, são rejeitados.
URL do Endpoint
POST https://netts.io/apiv2/bandwidthCabeçalhos da Requisição
| Cabeçalho | Obrigatório | Descrição |
|---|---|---|
| Content-Type | Sim | application/json |
| X-API-KEY | Sim | Sua chave de API do painel da Netts |
| X-Real-IP | Sim | Endereço IP da sua lista de permissões |
| X-Idempotency-Key | Não | Chave opcional gerada pelo cliente (base64) para tentar novamente com segurança sem duplicar pedidos. Se omitida, o servidor gera uma automaticamente |
Corpo da Requisição
json
{
"amount": 1500,
"receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"period": "5m"
}Parâmetros
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount | integer | Sim | Unidades de Bandwidth a serem alugadas (mínimo: 400, máximo: 5000) |
| receiveAddress | string | Sim | Endereço TRON que receberá a Bandwidth (T…, 34 caracteres, base58) |
| period | string | Sim | Duração do aluguel: "5m" (5 minutos) ou "1h" (1 hora) |
| trx_send | boolean | Não | Transação garantida: se não houver Bandwidth disponível, envia TRX para o endereço em vez disso para que a transação ainda ocorra. Funciona apenas quando amount = 400 (ignorado caso contrário). Padrão false |
| check | boolean | Não | Se true e o destinatário já tiver mais de 400 de Bandwidth, o pedido não é delegado e nenhum fundo é cobrado (status enough). Padrão false |
| test | boolean | Não | Execução de teste. Se true, o fluxo completo do pedido é simulado — a resposta informa o resultado que ocorreria e o preço que seria cobrado — sem qualquer ação on-chain e sem cobrança. Padrão false |
Exemplos de Requisição
Os exemplos abaixo também geram e enviam o
X-Idempotency-Keypara que uma repetição acidental não crie um segundo pedido. Consulte Idempotência para as regras completas.
cURL
bash
API_KEY="your_api_key"
ADDR="TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AMOUNT=1500
PERIOD="5m"
NONCE=$(( $(date +%s) / 2 )) # stable for retries within a 2s window; or your own order UUID
# X-Idempotency-Key = base64( HMAC-SHA256( API_KEY, "addr:amount:period:nonce" ) )
IDEMP=$(printf '%s' "${ADDR}:${AMOUNT}:${PERIOD}:${NONCE}" \
| openssl dgst -sha256 -hmac "$API_KEY" -binary | base64)
curl -X POST https://netts.io/apiv2/bandwidth \
-H "Content-Type: application/json" \
-H "X-API-KEY: $API_KEY" \
-H "X-Real-IP: your_whitelisted_ip" \
-H "X-Idempotency-Key: $IDEMP" \
-d "{\"amount\": $AMOUNT, \"receiveAddress\": \"$ADDR\", \"period\": \"$PERIOD\"}"Python
python
import time, hmac, hashlib, base64, requests
API_KEY = "your_api_key"
url = "https://netts.io/apiv2/bandwidth"
payload = {
"amount": 1500,
"receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"period": "5m",
}
# X-Idempotency-Key = base64( HMAC-SHA256( API_KEY, "addr:amount:period:nonce" ) )
# Generate ONCE per order and resend the same value on every retry.
nonce = str(int(time.time() // 2)) # 2s bucket; or your own order UUID
message = f"{payload['receiveAddress']}:{payload['amount']}:{payload['period']}:{nonce}"
idem_key = base64.b64encode(
hmac.new(API_KEY.encode(), message.encode(), hashlib.sha256).digest()
).decode()
headers = {
"Content-Type": "application/json",
"X-API-KEY": API_KEY,
"X-Real-IP": "your_whitelisted_ip",
"X-Idempotency-Key": idem_key,
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
detail = data.get("detail", {})
if response.status_code == 200 and detail.get("status") == "completed":
d = detail["data"]
print(f"Order ID: {d['orderId']}")
print(f"Hashes: {d['hash']}") # array of delegation tx hashes
print(f"Bandwidth: {d['bandwidth']} for {d['period']}")
print(f"Cost: {d['paidTRX']} TRX")
else:
print(f"Code: {detail.get('code')} | {detail.get('msg', detail)}")Um exemplo de cliente completo (Python + cURL) é fornecido com o pacote do serviço (handler_bandwidth/doc/client_example/).
Resposta
Sucesso — Bandwidth delegada (200 OK)
json
{
"detail": {
"code": 10000,
"status": "completed",
"msg": "Successful",
"data": {
"orderId": "B5M<key14>",
"paidTRX": "<amount charged in TRX>",
"fulfilledBy": "bandwidth",
"hash": ["a1b2c3...", "d4e5f6..."],
"bandwidth": 1500,
"period": "5m"
}
}
}Sucesso — TRX enviado em vez de Bandwidth (200 OK, apenas amount=400 + trx_send=true)
Quando o pool não tem Bandwidth e trx_send está ativado, TRX é enviado para o endereço para que a transação ainda seja executada. Uma taxa fixa se aplica neste caso, independentemente do período solicitado.
json
{
"detail": {
"code": 10000,
"status": "completed",
"msg": "Successful (sent TRX, bandwidth unavailable)",
"data": {
"orderId": "B5M<key14>",
"paidTRX": "<amount charged in TRX>",
"fulfilledBy": "trx",
"trxSendHash": ["<txid>"],
"hash": [],
"bandwidth": 400,
"period": "5m"
}
}
}Já suficiente — não cobrado (200 OK, apenas com check=true)
json
{
"detail": {
"code": 10002,
"status": "enough",
"msg": "enough band for 1 transfer",
"data": { "orderId": "B5M<key14>", "paidTRX": 0, "bandwidth": 400, "period": "5m" }
}
}Em processamento — provedor externo (202 Accepted)
Retornado quando o pedido é encaminhado para um provedor externo de forma assíncrona. Consulte o endpoint de status (abaixo) usando o orderId até que seja concluído.
json
{
"detail": {
"code": 10001,
"status": "processing",
"msg": "Order accepted, processed by an external provider. Poll the status endpoint.",
"data": { "orderId": "B5M<key14>", "bandwidth": 1500, "period": "5m" }
}
}Execução de teste (200 OK, apenas com test=true)
Todo o fluxo do pedido é simulado. testAction informa o que ocorreria e wouldCostTRX o que seria cobrado. Nada é delegado, nenhum TRX é enviado, nada é cobrado (paidTRX: 0).
json
{
"detail": {
"code": 10003,
"status": "test",
"msg": "Test run — no on-chain action, no charge",
"data": {
"orderId": "B5M<...>",
"testAction": "would_delegate",
"wouldCostTRX": "<amount that would be charged in TRX>",
"paidTRX": 0,
"bandwidth": 400,
"period": "5m",
"receiverFreeBandwidth": 600
}
}
}Valores de testAction: would_delegate (a Bandwidth seria delegada), would_trx_send (sem Bandwidth, amount=400 + trx_send → TRX seria enviado), enough (o destinatário já possui o suficiente, com check=true), ou would_error:<reason> (ex.: no_bandwidth, not_whitelisted).
Campos de Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| detail.code | integer | 10000 delegada/TRX, 10002 suficiente, 10001 processando |
| detail.status | string | completed / enough / processing / failed |
| detail.data.orderId | string | ID do pedido, formato B5M… (5m) / B1H… (1h) — use-o para o endpoint de status |
| detail.data.paidTRX | number | Valor cobrado em TRX (0 quando enough) |
| detail.data.fulfilledBy | string | bandwidth (delegada) / trx (TRX enviado) |
| detail.data.hash | array | Hashes das transações de delegação (até 10). Sempre uma matriz (vazia para o fluxo de TRX) |
| detail.data.trxSendHash | array | Hash(es) da transferência de TRX, presente apenas quando fulfilledBy = trx |
| detail.data.bandwidth | integer | Unidades de Bandwidth delegadas |
| detail.data.period | string | Período de aluguel (5m / 1h) |
Endpoint de Status
GET https://netts.io/apiv2/bandwidth/status/{orderId}Cabeçalhos: X-API-KEY + X-Real-IP (o pedido deve pertencer ao usuário autenticado).
| Estado do pedido | HTTP | code | status |
|---|---|---|---|
| Concluído | 200 | 10000 | completed (com hash / trxSendHash) |
| Em andamento | 200 | 10001 | processing |
| Já suficiente | 200 | 10002 | enough |
| Falhou | 200 | 5003 | failed |
| Não encontrado / não é seu | 404 | -1 | — |
Endpoint de Resgate
Resgate voluntariamente (desfaça a delegação) a Bandwidth de um dos seus pedidos delegados antes que o seu período expire. A Bandwidth é revogada automaticamente e o hash da transação é retornado.
POST https://netts.io/apiv2/bandwidth/reclaim/{orderId}Cabeçalhos: X-API-KEY + X-Real-IP (o pedido deve pertencer ao usuário autenticado).
| Estado do pedido | HTTP | code | status | Resultado |
|---|---|---|---|---|
| Delegado → resgatado agora | 200 | 10004 | reclaimed | reclaimHash (hashes das transações de revogação de delegação) |
| Já resgatado | 200 | 10004 | reclaimed | reclaimHash + msg "already reclaimed" |
| Não está em estado de delegação (nada a resgatar) | 400 | 5005 | failed | — |
| O resgate ainda não foi concluído | 503 | 5003 | failed | tente novamente em breve |
| Não encontrado / não é seu | 404 | -1 | — | — |
bash
curl -X POST https://netts.io/apiv2/bandwidth/reclaim/B5M<...> \
-H "X-API-KEY: your_api_key" -H "X-Real-IP: your_whitelisted_ip"json
{
"detail": {
"code": 10004,
"status": "reclaimed",
"msg": "Bandwidth reclaimed",
"data": { "orderId": "B5M<...>", "reclaimHash": ["<txid>"] }
}
}python
import requests
order_id = "B5M..." # the orderId from your rental response
url = f"https://netts.io/apiv2/bandwidth/reclaim/{order_id}"
headers = {"X-API-KEY": "your_api_key", "X-Real-IP": "your_whitelisted_ip"}
resp = requests.post(url, headers=headers)
detail = resp.json()["detail"]
if resp.status_code == 200 and detail["status"] == "reclaimed":
print(f"Reclaimed: {detail['data']['reclaimHash']} ({detail['msg']})")
else:
print(f"Code {detail.get('code')}: {detail.get('msg', detail)}")A cobrança do aluguel não é reembolsada em um resgate voluntário antecipado — o resgate apenas devolve a Bandwidth delegada ao pool antes do término do período.
Respostas de Erro
Erro de Autenticação (401)
json
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }Saldo Insuficiente (403)
json
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient funds" } }Erro de Validação (400)
json
{ "detail": { "code": 5004, "status": "failed", "msg": "Bandwidth amount out of range (400..5000)" } }Falha na Delegação / Serviço Indisponível (503)
json
{ "detail": { "code": 5003, "status": "failed", "msg": "Bandwidth delegation failed" } }Referência de Códigos de Erro
| Código | Descrição | Status HTTP |
|---|---|---|
10000 | Sucesso (delegado ou TRX enviado) | 200 |
10000 | Sucesso (resposta em cache) | 208 |
10001 | Aceito, em processamento por provedor externo | 202 |
10002 | Destinatário já possui Bandwidth suficiente (não cobrado) | 200 |
10003 | Execução de teste — prévia do resultado + preço, nada cobrado (test=true) | 200 |
10004 | Bandwidth resgatada (revogação voluntária da delegação) — reclaimHash retornado | 200 |
- | Requisição duplicada ainda em processamento | 409 |
-1 | Chave de API inválida / IP fora da lista de permissões | 401 |
1004 | Saldo insuficiente | 403 |
1005 | Nenhum endereço pagador para o usuário | 400 |
5004 | Quantidade/período inválido (validação) | 400 |
5005 | Nada a resgatar (o pedido não está em estado de delegação) | 400 |
5007 | Sem credenciamento — apenas um aluguel por vez; pedido anterior ainda ativo (aguarde até que termine) | 503 |
5008 | Sem credenciamento — apenas pedidos de 400 unidades são permitidos; credenciamento necessário para quantidades maiores | 503 |
5003 | Falha na delegação de Bandwidth / indisponível | 503 |
5000 | Erro interno do servidor | 500 |
Limites de Taxa
| Período | Limite | Descrição |
|---|---|---|
| 1 segundo | 50 requisições | Máximo de 50 requisições por segundo por IP |
Limite de Taxa Excedido (429)
json
{ "message": "API rate limit exceeded" }Idempotência
Envie o cabeçalho opcional X-Idempotency-Key para que uma repetição acidental não crie um segundo pedido — a resposta original é retornada com HTTP 208. Se você não enviar o cabeçalho, o servidor deriva uma chave automaticamente a partir dos parâmetros da sua requisição dentro de uma breve janela de tempo.
Como gerar a chave
A chave é base64( HMAC-SHA256( secret, message ) ) — uma string base64 de 44 caracteres, onde:
- secret = sua chave de API (
X-API-KEY); - message = os campos unidos por
:—receiveAddress:amount:period:nonce.
nonce é qualquer valor que seja estável entre tentativas do mesmo pedido lógico, mas diferente entre pedidos distintos — ex.: um UUID mantido por você para esse pedido, ou um timestamp aproximado em blocos. Gere a chave uma vez por pedido e reenvie exatamente o mesmo valor a cada nova tentativa.
python
import hmac, hashlib, base64, time
def make_idempotency_key(api_key, receive_address, amount, period, nonce=None):
if nonce is None:
nonce = str(int(time.time() // 2)) # 2-second bucket; or your own order UUID
message = f"{receive_address}:{amount}:{period}:{nonce}"
digest = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).digest()
return base64.b64encode(digest).decode() # 44-char base64bash
# then send it as a header:
-H "X-Idempotency-Key: <base64_key>"Incluir period na mensagem é importante: alugar para o mesmo endereço por 5m e por 1h são pedidos diferentes e devem produzir chaves diferentes.
Validação. Uma chave
X-Idempotency-Keyfornecida deve ser uma string base64 de 16–64 caracteres (conjunto de caracteresA–Z a–z 0–9 + / = _ -). Uma chave malformada ou excessivamente longa é rejeitada com HTTP 400 (code 5004).
| Código de Status | Significado |
|---|---|
| 200 | Processado com sucesso (primeira requisição) |
| 208 | Já processado com sucesso — resposta em cache retornada (sem segunda cobrança) |
| 409 | A mesma requisição está sendo processada no momento — aguarde, não tente novamente ainda |
Tentando novamente após uma falha. Apenas resultados bem-sucedidos (
completed/enough) são mantidos em cache. Se a tentativa anterior falhou ou expirou o tempo limite (nenhum fundo foi cobrado), você pode tentar novamente com segurança usando a mesmaX-Idempotency-Key— o pedido é tentado novamente em vez de retornar o erro antigo. Enquanto uma tentativa ainda estiver em andamento você recebe409; aguarde e tente novamente.
Observações
- Níveis de acesso: contas credenciadas alugam qualquer quantidade dentro dos limites do pool/máximos com pedidos simultâneos; sem credenciamento — 400 unidades uma vez (próximo pedido somente após o término do aluguel anterior). Entre em contato com o suporte da Netts para credenciamento.
- Mínimo: 400 unidades. Máximo: 5000 unidades por pedido (configuração atual).
- Períodos:
5m(300 s) e1h(3600 s). A Bandwidth é resgatada automaticamente quando o período expira. - Sem margem extra: exatamente a quantidade solicitada é delegada.
- hash é uma matriz: um único pedido pode produzir até 10 hashes de delegação — todos são retornados.
- Preços: cobrados em TRX, com base na quantidade e no período solicitados; as taxas podem variar de acordo com o horário do dia. Entre em contato com o suporte para verificar a tabela de preços atual.
- Compensação para pedidos pequenos (delegação): para pedidos abaixo de 1000 unidades, um valor fixo de 0.372 TRX é adicionado ao preço como compensação pela delegação e pelo resgate on-chain. Pedidos de 1000 unidades ou mais não possuem esse acréscimo.
- Compensação de envio de TRX: quando o pedido é atendido pelo envio de TRX (
fulfilledBy = trx), um valor fixo de 0.268 TRX é adicionado em substituição (compensação pela transferência de TRX on-chain). - trx_send: apenas para
amount = 400; se não houver Bandwidth disponível, TRX é enviado para o endereço para que a transação ainda ocorra. - check: ignora a delegação (e a cobrança) quando o destinatário já possui mais de 400 de Bandwidth.
- Formato do ID do pedido:
B5M…(5 minutos) /B1H…(1 hora). - Tempo limite de resposta: até ~12 segundos enquanto aguarda a delegação; normalmente de 1 a 2 segundos.