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

POST /apiv2/bandwidth

Alquile Bandwidth de TRON y deléguelo a una dirección de destinatario durante un período fijo (5 minutos o 1 hora).

⚠️ Niveles de acceso.

  • Las cuentas acreditadas alquilan cualquier cantidad (hasta 5000) dentro del tamaño del pool y de los límites máximos, con múltiples órdenes simultáneas. La acreditación es otorgada por el soporte de Netts.
  • Sin acreditación puede alquilar 400 unidades una sola vez — la siguiente orden solo se permite después de que finalice el alquiler anterior. Las solicitudes de cantidades distintas de 400, o una segunda orden mientras la primera todavía esté activa, son rechazadas.

URL del Endpoint

POST https://netts.io/apiv2/bandwidth

Encabezados de Solicitud

EncabezadoRequeridoDescripción
Content-Typeapplication/json
X-API-KEYSu clave API del panel de control de Netts
X-Real-IPDirección IP de su lista blanca
X-Idempotency-KeyNoClave opcional generada por el cliente (base64) para reintentar de forma segura sin duplicar órdenes. Si se omite, el servidor genera una automáticamente

Cuerpo de la Solicitud

json
{
    "amount": 1500,
    "receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "period": "5m"
}

Parámetros

ParámetroTipoRequeridoDescripción
amountintegerUnidades de Bandwidth a alquilar (mínimo: 400, máximo: 5000)
receiveAddressstringDirección TRON que recibirá el Bandwidth (T…, 34 caracteres, base58)
periodstringDuración del alquiler: "5m" (5 minutos) o "1h" (1 hora)
trx_sendbooleanNoTransacción garantizada: si no hay Bandwidth disponible, se envía TRX a la dirección en su lugar para que la transacción se procese igualmente. Solo funciona cuando amount = 400 (se ignora en caso contrario). Valor predeterminado false
checkbooleanNoSi es true y el destinatario ya tiene más de 400 de Bandwidth, la orden no se delega y no se cobran fondos (estado enough). Valor predeterminado false
testbooleanNoSimulación (Dry run). Si es true, se simula el flujo completo de la orden — la respuesta le informa del resultado que ocurriría y el precio que se cobraría — sin ninguna acción en la cadena y sin cobrar. Valor predeterminado false

Ejemplos de Solicitudes

Los ejemplos siguientes también construyen y envían el X-Idempotency-Key para que una repetición accidental no cree una segunda orden. Consulte Idempotencia para ver las reglas 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)}")

Se proporciona un ejemplo de cliente completo (Python + cURL) con el paquete del servicio (handler_bandwidth/doc/client_example/).

Respuesta

Éxito — Bandwidth delegado (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"
        }
    }
}

Éxito — TRX enviado en lugar de Bandwidth (200 OK, solo amount=400 + trx_send=true)

Cuando el pool no tiene Bandwidth y trx_send está habilitado, se envía TRX a la dirección para que la transacción se procese igualmente. En este caso se aplica un cargo fijo, independientemente del 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"
        }
    }
}

Ya suficiente — no se cobra (200 OK, solo con check=true)

json
{
    "detail": {
        "code": 10002,
        "status": "enough",
        "msg": "enough band for 1 transfer",
        "data": { "orderId": "B5M<key14>", "paidTRX": 0, "bandwidth": 400, "period": "5m" }
    }
}

En procesamiento — proveedor externo (202 Accepted)

Se devuelve cuando la orden se transfiere a un proveedor externo de forma asíncrona. Realice consultas periódicas (poll) al endpoint de estado (a continuación) utilizando orderId hasta que se complete.

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" }
    }
}

Ejecución de prueba (200 OK, solo con test=true)

Se simula todo el flujo de la orden. testAction le indica lo que sucedería y wouldCostTRX lo que se cobraría. No se delega nada, no se envía TRX, no se cobra nada (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 (el Bandwidth se delegaría), would_trx_send (sin Bandwidth, amount=400 + trx_send → se enviaría TRX), enough (el destinatario ya tiene suficiente, con check=true), o would_error:<reason> (por ej., no_bandwidth, not_whitelisted).

Campos de Respuesta

CampoTipoDescripción
detail.codeinteger10000 delegado/TRX, 10002 suficiente, 10001 en procesamiento
detail.statusstringcompleted / enough / processing / failed
detail.data.orderIdstringID de la orden, formato B5M… (5m) / B1H… (1h) — utilícelo para el endpoint de estado
detail.data.paidTRXnumberMonto cobrado en TRX (0 cuando es enough)
detail.data.fulfilledBystringbandwidth (delegado) / trx (TRX enviado)
detail.data.hasharrayHashes de transacciones de delegación (hasta 10). Siempre es un array (vacío para la rama TRX)
detail.data.trxSendHasharrayHash(es) de transferencia de TRX, presente solo cuando fulfilledBy = trx
detail.data.bandwidthintegerUnidades de Bandwidth delegadas
detail.data.periodstringPeríodo de alquiler (5m / 1h)

Endpoint de Estado

GET https://netts.io/apiv2/bandwidth/status/{orderId}

Encabezados: X-API-KEY + X-Real-IP (la orden debe pertenecer al usuario autenticado).

Estado de la ordenHTTPcodestatus
Completada20010000completed (con hash / trxSendHash)
En curso20010001processing
Ya suficiente20010002enough
Fallida2005003failed
No encontrada / no le pertenece404-1

Endpoint de Reclamación

Reclame voluntariamente (desdelegue) el Bandwidth de una de sus órdenes delegadas antes de que su período expire. El Bandwidth se desdelega automáticamente y se devuelve el hash de la transacción.

POST https://netts.io/apiv2/bandwidth/reclaim/{orderId}

Encabezados: X-API-KEY + X-Real-IP (la orden debe pertenecer al usuario autenticado).

Estado de la ordenHTTPcodestatusResultado
Delegada → reclamada ahora20010004reclaimedreclaimHash (hashes de transacciones de desdelegación)
Ya reclamada20010004reclaimedreclaimHash + mensaje "already reclaimed"
No está en estado delegado (nada que reclamar)4005005failed
La reclamación aún no se ha completado5035003failedreintente en breve
No encontrada / no le pertenece404-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)}")

El cargo por alquiler no se reembolsa en una reclamación anticipada voluntaria — reclamar solo devuelve el Bandwidth delegado al pool antes del final del período.

Respuestas de Error

Error de Autenticación (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" } }

Error de Validación (400)

json
{ "detail": { "code": 5004, "status": "failed", "msg": "Bandwidth amount out of range (400..5000)" } }

Error de Delegación / Servicio No Disponible (503)

json
{ "detail": { "code": 5003, "status": "failed", "msg": "Bandwidth delegation failed" } }

Referencia de Códigos de Error

CódigoDescripciónEstado HTTP
10000Éxito (delegado, o TRX enviado)200
10000Éxito (respuesta en caché)208
10001Aceptada, en procesamiento por proveedor externo202
10002El destinatario ya tiene suficiente Bandwidth (no cobrado)200
10003Ejecución de prueba — vista previa del resultado + precio, no se cobra nada (test=true)200
10004Bandwidth reclamado (desdelegación voluntaria) — se devuelve reclaimHash200
-Solicitud duplicada aún en procesamiento409
-1Clave API inválida / IP no está en la lista blanca401
1004Saldo insuficiente403
1005No hay dirección pagadora para el usuario400
5004Cantidad/período inválido (validación)400
5005Nada que reclamar (la orden no está en un estado delegado)400
5007Sin acreditación — solo un alquiler a la vez; la orden anterior sigue activa (espere a que finalice)503
5008Sin acreditación — solo se permiten órdenes de 400 unidades; se requiere acreditación para cantidades mayores503
5003Error en la delegación de Bandwidth / no disponible503
5000Error interno del servidor500

Límites de Tasa (Rate Limits)

PeríodoLímiteDescripción
1 segundo50 solicitudesMáximo 50 solicitudes por segundo por IP

Límite de Tasa Excedido (429)

json
{ "message": "API rate limit exceeded" }

Idempotencia

Envíe el encabezado opcional X-Idempotency-Key para que una repetición accidental no cree una segunda orden — se devuelve la respuesta original con HTTP 208. Si no envía el encabezado, el servidor deduce una clave automáticamente a partir de los parámetros de su solicitud dentro de un breve intervalo de tiempo.

Cómo formar la clave

La clave es base64( HMAC-SHA256( secret, message ) ) — una cadena en base64 de 44 caracteres, donde:

  • secret = su clave API (X-API-KEY);
  • message = los campos unidos con :receiveAddress:amount:period:nonce.

nonce es cualquier valor que sea estable a través de los reintentos de la misma orden lógica pero diferente entre órdenes distintas — por ej. un UUID que conserve para esa orden, o un bloque de marca temporal amplio. Genere la clave una vez por orden y reenvíe exactamente el mismo valor en cada reintento.

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 en el mensaje es importante: alquilar para la misma dirección por 5m y por 1h son órdenes diferentes y deben producir claves diferentes.

Validación. El encabezado X-Idempotency-Key suministrado debe ser una cadena base64 de 16–64 caracteres (conjunto de caracteres A–Z a–z 0–9 + / = _ -). Una clave mal formada o demasiado larga es rechazada con HTTP 400 (code 5004).

Código de EstadoSignificado
200Procesada exitosamente (primera solicitud)
208Ya procesada exitosamente — se devuelve la respuesta en caché (sin segundo cobro)
409La misma solicitud se está procesando actualmente — espere, no reintente todavía

Reintentar después de un fallo. Solo los resultados exitosos (completed / enough) se almacenan en caché. Si el intento anterior falló o agotó el tiempo de espera (no se cobraron fondos), puede reintentar de forma segura con el mismo X-Idempotency-Key — la orden se intentará de nuevo en lugar de devolver el error anterior. Mientras un intento siga en curso recibirá 409; espere y reintente.

Notas

  • Niveles de acceso: las cuentas acreditadas alquilan cualquier cantidad dentro de los límites del pool/máximos con órdenes simultáneas; sin acreditación — 400 unidades una sola vez (la siguiente orden solo después de que finalice el alquiler anterior). Póngase en contacto con el soporte de Netts para obtener la acreditación.
  • Mínimo: 400 unidades. Máximo: 5000 unidades por orden (configuración actual).
  • Períodos: 5m (300 s) y 1h (3600 s). El Bandwidth se reclama automáticamente cuando expira el período.
  • Sin búfer: se delega exactamente la cantidad solicitada.
  • hash es un array: una sola orden puede producir hasta 10 hashes de delegación — se devuelven todos.
  • Precios: se cobra en TRX, según la cantidad y el período solicitados; las tarifas pueden variar según la hora del día. Póngase en contacto con soporte para conocer los precios actuales.
  • Compensación por orden pequeña (delegación): para órdenes de menos de 1000 unidades, se añade un cargo fijo de 0.372 TRX al precio como compensación por la delegación y reclamación en la cadena. Las órdenes de 1000 unidades o más no tienen este recargo.
  • Compensación por envío de TRX: cuando la orden se cumple enviando TRX (fulfilledBy = trx), se añade en su lugar un cargo fijo de 0.268 TRX (compensación por la transferencia de TRX en la cadena).
  • trx_send: solo para amount = 400; si no hay Bandwidth disponible, se envía TRX a la dirección para que la transacción se procese igualmente.
  • check: omite la delegación (y el cobro) cuando el destinatario ya tiene más de 400 de Bandwidth.
  • Formato del ID de orden: B5M… (5 minutos) / B1H… (1 hora).
  • Tiempo de espera de respuesta (timeout): hasta ~12 segundos mientras se espera la delegación; típicamente 1–2 segundos.