Appearance
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/bandwidthCabeçalhos da requisição
| Header | Required | Description |
|---|---|---|
| Content-Type | Yes | application/json |
| X-API-KEY | Yes | Sua chave de API do painel da Netts |
| X-Real-IP | Yes | Endereço IP da sua lista de permissões (whitelist) |
| X-Idempotency-Key | No | 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
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | integer | Yes | Unidades de Bandwidth para alugar (mínimo: 400, máximo: 5000) |
| receiveAddress | string | Yes | Endereço TRON que receberá a Bandwidth (T…, 34 caracteres, base58) |
| period | string | Yes | Duração do aluguel: "5m" (5 minutos) ou "1h" (1 hora, apenas contas credenciadas) |
| trx_send | boolean | No | Transaçã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 |
| check | boolean | No | 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 | No | Modo 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-Keypara 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
| Field | Type | Description |
|---|---|---|
| detail.code | integer | 10000 delegada/TRX, 10002 suficiente, 10001 em processamento |
| 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á possui o suficiente | 200 | 10002 | enough |
| Falhou | 200 | 5003 | failed |
| Não encontrado / não é seu | 404 | -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 pedido | HTTP | code | status | Resultado |
|---|---|---|---|---|
| Delegado → revogado agora | 200 | 10004 | reclaimed | reclaimHash (hashes das txs de revogação) |
| Já revogado | 200 | 10004 | reclaimed | reclaimHash + msg "already reclaimed" |
| Não está em estado delegado (nada a revogar) | 400 | 5005 | failed | — |
| A revogação ainda não foi concluída | 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 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
| Code | Description | HTTP Status |
|---|---|---|
10000 | Sucesso (delegado ou TRX enviado) | 200 |
10000 | Sucesso (resposta em cache) | 208 |
10001 | Aceito, em processamento por provedor externo | 202 |
10002 | O 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 revogada (revogação voluntária) — reclaimHash retornado | 200 |
- | Pedido duplicado 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 revogar (o pedido não está em estado delegado) | 400 |
5007 | Sem credenciamento — apenas um aluguel por vez; o pedido anterior ainda está ativo (aguarde até que termine) | 503 |
5008 | Sem credenciamento — apenas pedidos de 400 unidades por 5 minutos são permitidos; credenciamento necessário para quantidades maiores ou 1 hora | 503 |
5003 | Falha na delegação de Bandwidth / indisponível | 503 |
5000 | Erro interno do servidor | 500 |
Limites de taxa
| Period | Limit | Description |
|---|---|---|
| 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 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 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
X-Idempotency-Keyfornecida deve ser uma string em base64 de 16 a 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 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 mesmaX-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 comenough(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"
}
}
}| Field | Description |
|---|---|
| paidTRX | Custo do serviço em TRX. Para contas pós-pagas, ele não é deduzido do depósito |
| paymentMode | postpaid |
| totalTRX | Valor 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
| Code | HTTP | Description |
|---|---|---|
1004 | 402 | Limite de crédito pós-pago atingido |
5032 | 503 | Preço temporariamente indisponível |
5034 | 503 | Faturamento temporariamente indisponível — o pedido não foi aceito |
5036 | 503 | Verificaçã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) e1h(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.