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

POST /apiv2/order1h ​

Cree una orden de alquiler de energía de 1 hora a través de múltiples proveedores de energía con conmutación por error automática.

URL del endpoint ​

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

Encabezados de solicitud ​

EncabezadoRequeridoDescripción
Content-TypeSíapplication/json
X-API-KEYSíSu clave API del panel de control de Netts
X-Real-IPSíDirección IP de su lista blanca

Cuerpo de solicitud ​

json
{
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}

Parámetros ​

ParámetroTipoRequeridoDescripción
amountintegerSíCantidad de Energy a alquilar (mínimo: 61000, máximo: 3000000)
receiveAddressstringSíDirección TRON que recibirá la energía (formato TRC-20)

Selección de proveedores ​

La API selecciona automáticamente el proveedor de energía óptimo basándose en:

  • Rentabilidad - Siempre encuentra el precio disponible más bajo
  • Disponibilidad - Garantiza reservas de energía suficientes
  • Fiabilidad - Utiliza proveedores con altas tasas de éxito
  • Velocidad - Prioriza los tiempos de entrega más rápidos

Ejemplos de peticiones ​

cURL ​

bash
curl -X POST https://netts.io/apiv2/order1h \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_api_key" \
  -H "X-Real-IP: your_whitelisted_ip" \
  -d '{
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
  }'

Python ​

python
import requests

url = "https://netts.io/apiv2/order1h"
headers = {
    "Content-Type": "application/json",
    "X-API-KEY": "your_api_key",
    "X-Real-IP": "your_whitelisted_ip"
}

payload = {
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}

response = requests.post(url, headers=headers, json=payload)
data = response.json()

if response.status_code == 200:
    detail = data.get('detail', {})
    order_data = detail.get('data', {})
    print(f"Order ID: {order_data.get('orderId')}")
    print(f"Transaction Hash: {order_data.get('hash')}")
    print(f"Energy Delivered: {order_data.get('energy')}")
    print(f"Cost: {order_data.get('paidTRX')} TRX")
    print(f"Delegate Address: {order_data.get('delegateAddress')}")
else:
    error_detail = data.get('detail', data)
    print(f"Error Code: {error_detail.get('code', 'N/A')}")
    print(f"Error Message: {error_detail.get('msg', error_detail)}")

Respuesta ​

Respuesta exitosa (200 OK) ​

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 2.23 TRX deducted",
        "data": {
            "orderId": "1H123456",
            "paidTRX": 2.23,
            "hash": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
            "delegateAddress": "TNp5gsJhBmZFXgCdgjMgr8pEZ8fHgXUHDq",
            "energy": 131050
        }
    }
}

Campos de respuesta ​

CampoTipoDescripción
detail.codeintegerSiempre 10000 para órdenes exitosas
detail.msgstringMensaje de éxito con el monto deducido
detail.data.orderIdstringID de orden unificado (formato: 1H{request_id})
detail.data.paidTRXnumberCosto total en TRX (incluye la tarifa de activación si la dirección no estaba activada)
detail.data.hashstring | nullHash de la transacción. El campo siempre está presente pero puede estar vacío - algunos proveedores no devuelven el hash de inmediato. Use /apiv2/order_check después de 1 minuto para obtener el hash
detail.data.delegateAddressstringDirección del grupo (pool) que delegó la energía
detail.data.energyintegerCantidad de Energy + margen de búfer (típicamente +50)

Respuestas de error ​

Error de autenticación (401) ​

json
{
    "detail": "Invalid API key or IP not in whitelist"
}

Saldo insuficiente (403) ​

json
{
    "code": 1004,
    "msg": "Insufficient funds. Required: 2.23 TRX, Available: 1.50 TRX"
}

Servicio no disponible (503) ​

json
{
    "code": 5003,
    "msg": "Service temporarily unavailable. All energy providers are currently unavailable."
}

Errores del proveedor (503) ​

json
{
    "code": 5001,
    "msg": "Energy provider temporarily unavailable"
}
json
{
    "code": 5002,
    "msg": "Energy provider temporarily unavailable"
}
json
{
    "code": 5004,
    "msg": "Energy provider requires higher minimum amount"
}

Error interno del servidor (500) ​

json
{
    "code": 5000,
    "msg": "Internal server error occurred"
}

Referencia de códigos de error ​

CódigoDescripciónEstado HTTP
10000Éxito200
10000Éxito (respuesta en caché)208
-Petición duplicada aún en procesamiento409
1004Saldo insuficiente403
5000Error interno del servidor500
5001Proveedor de energía no disponible503
5002Proveedor de energía no disponible503
5003Servicio de energía no disponible503
5004Mínimo del proveedor de energía no alcanzado503

Límites de tasa ​

Se aplican los siguientes límites de tasa a este endpoint (por dirección IP):

PeriodoLímiteDescripción
1 segundo50 peticionesMáximo de 50 peticiones por segundo

Encabezados de límite de tasa ​

http
RateLimit-Limit: 50
RateLimit-Remaining: 49
RateLimit-Reset: 1
X-RateLimit-Limit-Second: 50
X-RateLimit-Remaining-Second: 49

Límite de tasa excedido (429) ​

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

Idempotencia ​

La API admite idempotencia para evitar el procesamiento de órdenes duplicadas. Cuando envía varias peticiones idénticas, el sistema garantiza que la orden se procese solo una vez.

Cómo funciona la idempotencia ​

La singularidad de la petición se determina mediante una combinación de:

  • Marca de tiempo de la petición (ventana de 1 segundo)
  • Cantidad de energía
  • Dirección del receptor
  • Clave API

A cada petición se le asigna una ventana de unicidad de 1 segundo. Para proteger el sistema contra abusos y garantizar un procesamiento adecuado, las peticiones con parámetros idénticos no se pueden enviar con una frecuencia superior a una vez por segundo.

Comportamiento actual: El sistema protege automáticamente a los clientes contra reintentos erróneos sobre energía ya ordenada. Si accidentalmente envía la misma petición dos veces, no se le cobrará dos veces.

Proporcionar su propia clave ​

Puede tomar el control de la idempotencia enviando el encabezado X-Idempotency-Key. Cuando está presente, ese valor por sí solo decide si una petición es repetida y no se utiliza la combinación automática anterior. Cuando no está presente, nada cambia: el servidor deduce la clave por usted.

EncabezadoX-Idempotency-Key
FormatoExactamente 64 caracteres hexadecimales en minúsculas — un hash SHA-256
Duración24 horas a partir de la primera petición que lleve esa clave
AlcanceSu cuenta. El mismo valor enviado por una cuenta diferente nunca devuelve su resultado

Una clave con cualquier otro formato (un UUID con guiones, base64, hexadecimal en mayúsculas) se rechaza con 400 antes de que se cree la orden y antes de que se cobre nada:

json
{
    "detail": "Invalid idempotency key format. Must be 64-character hexadecimal string."
}

El formato difiere de otros endpoints. /apiv2/withdraw, /apiv2/bandwidth y el orquestador aceptan una clave en base64 de 16 a 64 caracteres. Este endpoint solo acepta un resumen hexadecimal de 64 caracteres, por lo que el código de generación de claves copiado de esos endpoints devolverá 400 aquí.

Cómo formar la clave ​

Derívela a partir de su clave API. Eso hace que el valor sea único para su cuenta, reproducible en un reintento e imposible de obtener para cualquier otra persona:

python
import hashlib
import hmac

def make_idempotency_key(api_key: str, address: str, amount: int, nonce: str) -> str:
    message = f"{address}:{amount}:{nonce}"
    return hmac.new(api_key.encode(), message.encode(), hashlib.sha256).hexdigest()

El nonce pertenece a la orden, no a la petición. Elíjalo una vez, cuando la orden se cree en su lado, y pase ese mismo valor en cada envío de esa orden, tanto en el primer intento como en cada reintento. Generar un valor nuevo dentro de la función de envío (str(uuid.uuid4()) en cada llamada) le da a cada intento una clave diferente, por lo que un reintento tras un tiempo de espera se acepta como una segunda orden y se cobra nuevamente. La opción correcta más simple es el ID de orden que ya tiene: existe antes del primer intento y sobrevive al reinicio de su proceso.

python
# una vez, cuando la orden aparece en su sistema
order = create_order(address="TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", amount=131000)

# en el primer intento y en cada reintento — las mismas tres entradas, la misma clave
key = make_idempotency_key(API_KEY, order.address, order.amount, order.id)

headers = {
    "Content-Type": "application/json",
    "X-API-KEY": API_KEY,
    "X-Idempotency-Key": key,
}

Una clave dura 24 horas. Después de eso, el mismo nonce queda libre nuevamente e inicia una nueva orden.

No use un valor al que cualquiera pudiera llegar: 64 ceros, el hash de una palabra fija. Las claves comparten un único espacio entre cuentas. Dicha colisión nunca expone la orden de otra cuenta, pero su petición se rechazará con 409 hasta que expire la clave de ellos, lo cual no es la respuesta que desea a mitad de un reintento.

Realizar dos órdenes idénticas ​

A veces realmente desea la misma orden dos veces: la misma cantidad de energía para la misma dirección, una tras otra. La clave automática no puede distinguir eso de un reintento: las dos peticiones son idénticas byte por byte, y lo único que las separa es el momento en que llegan.

Sin una clave propia, el resultado depende del intervalo entre ellas:

Intervalo entre las dos peticionesQué sucede
Dentro de la misma ventana de 1 segundoLa segunda petición se toma como una repetición. No se ejecuta: obtiene 208 y la respuesta de la primera orden, incluido orderId. No se cobra nada por ella
Con más de un segundo de diferenciaDos claves diferentes — ambas órdenes se crean y ambas se cobran

Por lo tanto, si confía en la clave automática, deje más de un segundo entre dos órdenes idénticas y lea el código de estado: 208 significa que la orden que acaba de enviar no se ejecutó.

Una pausa es una solución provisional, no definitiva. Separa cada petición, incluidas aquellas que nunca tuvo la intención de repetir: un reintento tras un tiempo de espera agotado, un doble clic, un mensaje reenviado por su cola. Estas también llegan después de la ventana, por lo que se procesan como órdenes independientes y se cobran por separado. El tiempo de espera de respuesta de este endpoint es de 10 segundos, lo que ya está muy fuera de la ventana: la clave automática no protege un reintento que sigue a un tiempo de espera agotado.

Su propia clave elimina la incertidumbre, porque la decisión se traslada a la única parte que conoce la respuesta:

Lo que está haciendoLo que envíaResultado
Una segunda orden genuinamente nuevaUn nuevo nonceUna nueva clave — la orden se procesa
Un reintento de una orden cuyo resultado desconoceEl nonce del primer intentoLa misma clave — 208, la respuesta original, sin segundo cobro

La segunda fila es la razón por la que existe el encabezado y es donde las implementaciones suelen fallar: consulte la nota debajo de Cómo formar la clave.

Códigos de estado HTTP para peticiones duplicadas ​

Código de estadoNombreDescripción
200OKOrden procesada exitosamente (primera petición)
208Already ReportedLa orden ya fue procesada, devolviendo respuesta en caché
409ConflictLa petición se está procesando actualmente, no reintente

Petición duplicada - Ya procesada (208) ​

Cuando se recibe una petición duplicada para una orden ya completada:

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 2.54 TRX deducted",
        "data": {
            "hash": "9e4c20e21e01e4c39b21b670d1ea1fc1e4b0de94d8fbd4c190d5378ba911dfae",
            "energy": 65050,
            "orderId": "1H70bcc7962a",
            "paidTRX": 2.535,
            "delegateAddress": "TNp5gsJhBmZFXgCdgjMgr8pEZ8fHgXUHDq"
        }
    },
    "idempotency": {
        "status": "completed",
        "cached": true,
        "original_created_at": "2025-12-03T10:34:49.104896"
    }
}

El cuerpo de la respuesta es idéntico a la respuesta exitosa original, con un objeto idempotency adicional que indica que se trata de una respuesta en caché.

Petición duplicada - Aún en procesamiento (409) ​

Cuando llega una petición duplicada mientras la original todavía se está procesando:

json
{
    "success": false,
    "error": "duplicate_request_processing",
    "message": "This request is currently being processed. Please wait and do not retry.",
    "idempotency_key": "b9e67b2412d33c92a4f0e1c3d5b7a9f2e4c6d8b0a2f4e6c8d0b2a4f6e8c0d2b4",
    "retry_after_seconds": 3
}

Recomendación: Espere los retry_after_seconds especificados antes de verificar el estado de la orden.

Mejores prácticas ​

  • No envíe peticiones paralelas con los mismos parámetros; espere cada respuesta
  • Use un nuevo nonce para cada nueva orden, y el nonce del primer intento para cada reintento de la misma
  • Nunca regenere el nonce al momento de enviar — un reintento debe reproducir la clave del primer intento, no una nueva
  • Maneje las respuestas 409 esperando, no reintentando de inmediato
  • Verifique el campo idempotency.cached para identificar respuestas en caché — un 208 significa que la orden que acaba de enviar no se ejecutó

Cuentas de pospago ​

Las cuentas con facturación de pospago utilizan el mismo endpoint, URL, encabezados y cuerpo de petición que todos los demás. La diferencia radica en cómo se paga la orden:

  • No se deduce nada de su depósito. Cada orden exitosa se agrega al saldo pendiente de su cuenta en la moneda de liquidación acordada en su contrato. Usted la paga mediante factura, según su acuerdo.
  • Su cuenta tiene un límite de crédito. Mientras el importe adeudado esté dentro del límite, las órdenes se aceptan incluso con un depósito de cero.
  • Solo se facturan los servicios entregados. Una orden que sea rechazada o no ejecutada no cuesta nada.
  • Si la dirección receptora debe activarse, la activación forma parte de la misma orden y se factura como un cargo independiente.

La facturación de pospago la habilita Netts para una cuenta previa solicitud. Cada respuesta le indica cómo se paga la orden: paymentMode es postpaid o prepaid.

Campos adicionales de la petición ​

ParámetroTipoRequeridoDescripción
testbooleanNotrue — calcula solo el precio. No se ordena, entrega ni factura nada
freezePricebooleanNotrue — fija el precio bajo su contrato durante 60 segundos. No se ordena ni factura nada
quoteIdstringNoCrea la orden al precio de una cotización emitida mediante freezePrice
priceCurrencystringNoTRX (predeterminado) o la moneda de su contrato, como en settlement.asset. Para cuentas de pospago siempre se incluyen los montos en la moneda de su contrato

quoteId no se puede combinar con test o freezePrice. Cualquier otro campo en el cuerpo de la petición será rechazado.

Comprobación de precio (test: true) ​

json
{
    "amount": 65000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "test": true
}
json
{
    "detail": {
        "code": 10010,
        "msg": "Test calculation",
        "data": {
            "amount": 65000,
            "unitPriceSun": "20",
            "discount": null,
            "energyTRX": "1.300000",
            "activationTRX": "1.100000",
            "wouldCostTRX": "2.400000",
            "paidTRX": 0,
            "paymentMode": "postpaid",
            "activationCheck": "inactive",
            "alt": {"USDC": {"energy": "0.430541", "activation": "0.364304", "total": "0.794845"}},
            "fxAt": "2026-10-19T07:15:18.469870+00:00"
        }
    }
}
CampoDescripción
unitPriceSunPrecio por unidad de energía en SUN, incluido su descuento personal si tiene uno
discountSu descuento personal (type, value) o null
energyTRX / activationTRX / wouldCostTRXEnergía, activación (si la dirección la necesita) y total, en TRX
activationCheckinactive — la dirección será activada y facturada; active — sin activación; unknown — no se pudo verificar en este momento
alt.<currency>Los mismos montos en la moneda de su contrato
fxAtMomento del tipo de cambio utilizado para los montos en la moneda de su contrato

Cotización de precio fijo (freezePrice: true) ​

Utilice una cotización para fijar el precio según su contrato antes de ordenar.

  1. Envíe la orden con "freezePrice": true. La respuesta tiene el código 10011 (Quote issued), los mismos campos que una verificación de precio, más quoteId y expiresAt.
  2. Dentro de 60 segundos envíe la orden con "quoteId": "<quoteId>" y la misma amount y receiveAddress.
  3. La orden se factura al precio cotizado (el precio según su contrato en el momento de la cotización), incluso si el precio cambia en el ínterin.

Una cotización se puede utilizar una sola vez y solo para el mismo producto: una cotización de 1 hora no puede pagar una orden de 5 minutos. Una cotización vencida o ya utilizada se rechaza y no se ordena nada.

json
{
    "amount": 65000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "quoteId": "q_4f540f16a2c94b7f8e3d1a6b5c0e9d72"
}

Orden exitosa ​

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 1.30 TRX for energy + 1.10 TRX for address activation, postpaid",
        "data": {
            "orderId": "1Hf9544a1508",
            "paidTRX": 2.4,
            "hash": "032bda8fa6911b42c15a6d8d30520dc22bcc4077972a1503b6a3fae491967eb4",
            "delegateAddress": "TVnkj2jHKgmea8DVJFo2teD7rRSpH51bne",
            "energy": 65000,
            "activationHash": "259e1ab276114ae717a6f62d7d25eb1f89a2dccb637cbe41be626df3c2a78519",
            "paymentMode": "postpaid",
            "energyTRX": "1.300000",
            "activationTRX": "1.100000",
            "totalTRX": "2.400000"
        }
    }
}
CampoDescripción
paidTRXCosto del servicio en TRX. Para cuentas de pospago no se deduce del depósito
paymentModepostpaid
energyTRX / activationTRX / totalTRXMontos exactos, 6 decimales
quoteId, altPresentes cuando la orden se realizó con una cotización: el ID de cotización y los montos cotizados
activationFinalPresente y false únicamente cuando el monto de activación es preliminar; el monto final aparece en su factura

Todos los demás campos son los mismos que para las órdenes de prepago.

Límite de crédito alcanzado (402) ​

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

La orden no se ejecuta y no se factura nada. Se aceptan nuevas órdenes nuevamente una vez que se registre su pago o se incremente su límite.

Códigos de error de pospago ​

CódigoHTTPDescripción
10010200Resultado de la comprobación de precio (test)
10011200Cotización emitida (freezePrice)
1004402Límite de crédito de pospago alcanzado
4100400Petición no válida
4101400priceCurrency no compatible
4102400quoteId combinado con test o freezePrice
4103409Cotización ya utilizada
4104409Cotización vencida
4105409Clave de idempotencia ya utilizada para una petición diferente
4106404Cotización no encontrada
4107409Los parámetros de la orden difieren de la cotización
4108400Formato de quoteId no válido
4109422No disponible para subcuentas
5032503Precio no disponible temporalmente
5033503Tipo de cambio no disponible temporalmente
5034503Facturación no disponible temporalmente — la orden no fue aceptada
5036503Verificación de crédito no disponible temporalmente — reintente más tarde

Para todas las respuestas 4xx y 503 anteriores no se ordena nada ni se factura nada.

Notas ​

  • La energía se entrega instantáneamente tras una orden exitosa (típicamente entre 0.5 y 10 segundos)
  • Tiempo de espera de respuesta de la API: Máximo 10 segundos, normalmente responde en hasta 2 segundos
  • Activación de dirección: Si la dirección receptora no está activada, Netts la activa a precio de costo
  • Demora de activación: Para direcciones no activadas, la respuesta de la API puede demorar hasta 6 segundos debido al proceso de activación
  • Las órdenes se procesan 24/7 con conmutación por error automática de proveedores
  • Cantidad mínima de energía: 61,000 unidades
  • Cantidad máxima de energía: 3,000,000 de unidades por orden
  • Búfer de energía: +50 unidades agregadas automáticamente para compensación del proveedor (sin costo)
  • Hash de transacción: El campo siempre está presente pero puede estar vacío si el proveedor no lo devuelve de inmediato. Para recuperar el hash, llame a /apiv2/order_check no antes de 1 minuto después de realizar la orden
  • Selección de proveedores: Automática según el costo y la disponibilidad
  • Formato del ID de orden: 1H{request_id} para seguimiento unificado
  • Precios: Dinámicos según la hora del día y la cantidad de energía
  • Duración: Fija de 1 hora (3600 segundos)
  • Límite de tasa: 50 peticiones por segundo por dirección IP