Skip to content
Translated page. The English version is the source of truth.

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/bandwidth

Cabeçalhos da Requisição

CabeçalhoObrigatórioDescrição
Content-TypeSimapplication/json
X-API-KEYSimSua chave de API do painel da Netts
X-Real-IPSimEndereço IP da sua lista de permissões
X-Idempotency-KeyNãoChave 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âmetroTipoObrigatórioDescrição
amountintegerSimUnidades de Bandwidth a serem alugadas (mínimo: 400, máximo: 5000)
receiveAddressstringSimEndereço TRON que receberá a Bandwidth (T…, 34 caracteres, base58)
periodstringSimDuração do aluguel: "5m" (5 minutos) ou "1h" (1 hora)
trx_sendbooleanNãoTransaçã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
checkbooleanNãoSe 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
testbooleanNãoExecuçã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-Key para 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

CampoTipoDescrição
detail.codeinteger10000 delegada/TRX, 10002 suficiente, 10001 processando
detail.statusstringcompleted / enough / processing / failed
detail.data.orderIdstringID do pedido, formato B5M… (5m) / B1H… (1h) — use-o para o endpoint de status
detail.data.paidTRXnumberValor cobrado em TRX (0 quando enough)
detail.data.fulfilledBystringbandwidth (delegada) / trx (TRX enviado)
detail.data.hasharrayHashes das transações de delegação (até 10). Sempre uma matriz (vazia para o fluxo de TRX)
detail.data.trxSendHasharrayHash(es) da transferência de TRX, presente apenas quando fulfilledBy = trx
detail.data.bandwidthintegerUnidades de Bandwidth delegadas
detail.data.periodstringPerí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 pedidoHTTPcodestatus
Concluído20010000completed (com hash / trxSendHash)
Em andamento20010001processing
Já suficiente20010002enough
Falhou2005003failed
Não encontrado / não é seu404-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 pedidoHTTPcodestatusResultado
Delegado → resgatado agora20010004reclaimedreclaimHash (hashes das transações de revogação de delegação)
Já resgatado20010004reclaimedreclaimHash + msg "already reclaimed"
Não está em estado de delegação (nada a resgatar)4005005failed
O resgate ainda não foi concluído5035003failedtente novamente em breve
Não encontrado / não é seu404-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ódigoDescriçãoStatus HTTP
10000Sucesso (delegado ou TRX enviado)200
10000Sucesso (resposta em cache)208
10001Aceito, em processamento por provedor externo202
10002Destinatário já possui Bandwidth suficiente (não cobrado)200
10003Execução de teste — prévia do resultado + preço, nada cobrado (test=true)200
10004Bandwidth resgatada (revogação voluntária da delegação) — reclaimHash retornado200
-Requisição duplicada ainda em processamento409
-1Chave de API inválida / IP fora da lista de permissões401
1004Saldo insuficiente403
1005Nenhum endereço pagador para o usuário400
5004Quantidade/período inválido (validação)400
5005Nada a resgatar (o pedido não está em estado de delegação)400
5007Sem credenciamento — apenas um aluguel por vez; pedido anterior ainda ativo (aguarde até que termine)503
5008Sem credenciamento — apenas pedidos de 400 unidades são permitidos; credenciamento necessário para quantidades maiores503
5003Falha na delegação de Bandwidth / indisponível503
5000Erro interno do servidor500

Limites de Taxa

PeríodoLimiteDescrição
1 segundo50 requisiçõesMá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 base64
bash
# 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-Key fornecida deve ser uma string base64 de 16–64 caracteres (conjunto de caracteres A–Z a–z 0–9 + / = _ -). Uma chave malformada ou excessivamente longa é rejeitada com HTTP 400 (code 5004).

Código de StatusSignificado
200Processado com sucesso (primeira requisição)
208Já processado com sucesso — resposta em cache retornada (sem segunda cobrança)
409A 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 mesma X-Idempotency-Key — o pedido é tentado novamente em vez de retornar o erro antigo. Enquanto uma tentativa ainda estiver em andamento você recebe 409; 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) e 1h (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.