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

POST /apiv2/bandwidth ​

Alugue Bandwidth da TRON e delegue-a para um endereço de destinatário por um período fixo: 5 minutos, ou 1 hora para contas credenciadas.

⚠️ Níveis de acesso.

  • Contas credenciadas alugam qualquer quantidade (até 5000) por 5 minutos ou 1 hora 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 por 5 minutos, uma única vez — o próximo pedido só é permitido após o término do aluguel anterior. Pedidos para quantidades diferentes de 400, por 1 hora, 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 ​

HeaderRequiredDescription
Content-TypeYesapplication/json
X-API-KEYYesSua chave de API do painel da Netts
X-Real-IPYesEndereço IP da sua lista de permissões (whitelist)
X-Idempotency-KeyNoChave 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 ​

ParameterTypeRequiredDescription
amountintegerYesUnidades de Bandwidth para alugar (mínimo: 400, máximo: 5000)
receiveAddressstringYesEndereço TRON que receberá a Bandwidth (T…, 34 caracteres, base58)
periodstringYesDuração do aluguel: "5m" (5 minutos) ou "1h" (1 hora, apenas contas credenciadas)
trx_sendbooleanNoTransação garantida: se não houver Bandwidth disponível, envia TRX para o endereço para que a transação ainda ocorra. Funciona apenas quando amount = 400 (ignorado caso contrário). Padrão false
checkbooleanNoSe 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
testbooleanNoModo de teste (dry run). 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 ​

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 ver 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 completo de cliente (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 possui Bandwidth e trx_send está ativado, o TRX é enviado para o endereço para que a transação ainda passe. Uma taxa fixa é aplicada 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á possui quantidade 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 a 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 aconteceria 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> (por exemplo, no_bandwidth, not_whitelisted).

Campos da resposta ​

FieldTypeDescription
detail.codeinteger10000 delegada/TRX, 10002 suficiente, 10001 em processamento
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á possui o suficiente20010002enough
Falhou2005003failed
Não encontrado / não é seu404-1—

Endpoint de Revogação ​

Revogue voluntariamente (undelegate) a Bandwidth de um dos seus pedidos delegados antes do término do seu período. 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 → revogado agora20010004reclaimedreclaimHash (hashes das txs de revogação)
Já revogado20010004reclaimedreclaimHash + msg "already reclaimed"
Não está em estado delegado (nada a revogar)4005005failed—
A revogação ainda não foi concluída5035003failedtente 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 uma revogação antecipada voluntária — a revogação 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 ​

CodeDescriptionHTTP Status
10000Sucesso (delegado ou TRX enviado)200
10000Sucesso (resposta em cache)208
10001Aceito, em processamento por provedor externo202
10002O destinatá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 revogada (revogação voluntária) — reclaimHash retornado200
-Pedido duplicado 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 revogar (o pedido não está em estado delegado)400
5007Sem credenciamento — apenas um aluguel por vez; o pedido anterior ainda está ativo (aguarde até que termine)503
5008Sem credenciamento — apenas pedidos de 400 unidades por 5 minutos são permitidos; credenciamento necessário para quantidades maiores ou 1 hora503
5003Falha na delegação de Bandwidth / indisponível503
5000Erro interno do servidor500

Limites de taxa ​

PeriodLimitDescription
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 o código 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 formar a chave ​

A chave é base64( HMAC-SHA256( secret, message ) ) — uma string em base64 de 44 caracteres, onde:

  • secret = sua chave de API (X-API-KEY);
  • message = os campos unidos com : — receiveAddress:amount:period:nonce.

nonce é qualquer valor que seja estável entre tentativas de repetição do mesmo pedido lógico, mas diferente entre pedidos distintos — por exemplo, um UUID que você mantém para esse pedido ou um intervalo de timestamp aproximado. Gere a chave uma vez por pedido e reenvie exatamente o mesmo valor a cada 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 X-Idempotency-Key fornecida deve ser uma string em base64 de 16 a 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 armazenados em cache. Se a tentativa anterior falhou ou expirou por tempo limite (nenhum fundo foi cobrado), você pode com segurança tentar novamente com a mesma X-Idempotency-Key — o pedido é tentado novamente em vez de retornar o erro antigo. Enquanto uma tentativa ainda estiver em andamento, você receberá 409; aguarde e tente novamente.

Contas Pós-pagas ​

As contas com faturamento pós-pago utilizam o mesmo endpoint, URL, cabeçalhos e corpo de requisição que todos os outros usuários. A diferença está em como o pedido é pago:

  • Nada é deduzido do seu depósito. Cada pedido entregue é adicionado ao saldo devedor da sua conta na moeda de liquidação acordada em seu contrato. Você efetua o pagamento via fatura, de acordo com o seu contrato.
  • Sua conta possui um limite de crédito. Enquanto o valor devido estiver dentro do limite, os pedidos serão aceitos mesmo com saldo de depósito zerado. Aluguéis de 5 minutos e de 1 hora contam para o mesmo limite de Bandwidth.
  • Apenas os serviços entregues são faturados: Bandwidth delegada ao endereço ou TRX enviado como alternativa (fulfilledBy = trx). O valor é o mesmo aplicado aos pedidos pré-pagos.
  • Um pedido que seja rejeitado, não executado, uma execução de teste (test: true) ou respondido com enough (check: true) não tem custo algum.
  • Uma revogação antecipada voluntária não reduz o valor devido, exatamente como ocorre em pedidos pré-pagos.
  • Níveis de acesso, quantidades, períodos e todas as outras regras deste endpoint são idênticos aos das contas pré-pagas.

O faturamento pós-pago é ativado pela Netts para uma conta mediante solicitação. Cada resposta informa a modalidade de pagamento do pedido: paymentMode será postpaid ou prepaid.

Verificação de preço (test: true) ​

json
{
    "amount": 1000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "period": "5m",
    "test": true
}
json
{
    "detail": {
        "code": 10003,
        "status": "test",
        "msg": "Test run — no on-chain action, no charge",
        "data": {
            "orderId": "B5M1a2b3c4d5e6f70",
            "testAction": "would_delegate",
            "wouldCostTRX": 0.7,
            "paidTRX": 0,
            "bandwidth": 1000,
            "period": "5m",
            "receiverFreeBandwidth": 600,
            "paymentMode": "postpaid"
        }
    }
}

wouldCostTRX é o valor que seria adicionado ao seu saldo devedor, em TRX. Nada é delegado ou faturado.

Pedido bem-sucedido ​

json
{
    "detail": {
        "code": 10000,
        "status": "completed",
        "msg": "Successful, 0.700000 TRX, postpaid",
        "data": {
            "orderId": "B5M0f9e8d7c6b5a41",
            "paidTRX": 0.7,
            "fulfilledBy": "bandwidth",
            "hash": ["<txid>"],
            "bandwidth": 1000,
            "period": "5m",
            "paymentMode": "postpaid",
            "totalTRX": "0.700000"
        }
    }
}
FieldDescription
paidTRXCusto do serviço em TRX. Para contas pós-pagas, ele não é deduzido do depósito
paymentModepostpaid
totalTRXValor exato, 6 casas decimais

Todos os outros campos, incluindo o fluxo de TRX (fulfilledBy = trx, trxSendHash), são os mesmos dos pedidos pré-pagos.

Limite de crédito atingido (402) ​

json
{
    "detail": {
        "code": 1004,
        "msg": "Postpaid credit limit reached.",
        "paymentMode": "postpaid",
        "reason": "limit_reached"
    }
}

O pedido não é executado e nada é faturado. Novos pedidos serão aceitos novamente assim que o pagamento for registrado ou o limite for aumentado.

Códigos de erro pós-pagos ​

CodeHTTPDescription
1004402Limite de crédito pós-pago atingido
5032503Preço temporariamente indisponível
5034503Faturamento temporariamente indisponível — o pedido não foi aceito
5036503Verificação de crédito temporariamente indisponível — tente novamente mais tarde

Para todas as respostas acima, nada é solicitado e nada é faturado. Todos os outros códigos são os mesmos dos pedidos pré-pagos.

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 por 5 minutos, uma única vez (próximo pedido somente após o término do aluguel anterior). Entre em contato com o suporte da Netts para obter o credenciamento.
  • Mínimo: 400 unidades. Máximo: 5000 unidades por pedido (configuração atual).
  • Períodos: 5m (300 s) e 1h (3600 s, apenas contas credenciadas). A Bandwidth é revogada automaticamente quando o período expira.
  • Sem margem adicional (buffer): 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 saber os preços vigentes.
  • 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 revogação on-chain. Pedidos de 1000 unidades ou mais não possuem essa adição.
  • Compensação por 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, o 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.