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

POST /apiv2/order1h

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

URL del endpoint

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

Encabezados de solicitud

EncabezadoRequeridoDescripción
Content-Typeapplication/json
X-API-KEYSu clave API del panel de Netts
X-Real-IPDirección IP de su lista blanca

Cuerpo de la solicitud

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

Parámetros

ParámetroTipoRequeridoDescripción
amountenteroCantidad de Energy a alquilar (mínimo: 61000, máximo: 3000000)
receiveAddresscadenaDirección TRON que recibirá la Energy (formato TRC-20)

Selección de proveedor

La API selecciona automáticamente el proveedor de Energy óptimo en función de:

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

Solicitudes de ejemplo

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": "a1b2c3d4e5f6789...",
            "delegateAddress": "TDelegatePoolAddress...",
            "energy": 131050
        }
    }
}

Campos de respuesta

CampoTipoDescripción
detail.codeenteroSiempre 10000 para órdenes exitosas
detail.msgcadenaMensaje de éxito con la cantidad deducida
detail.data.orderIdcadenaID unificado de la orden (formato: 1H{request_id})
detail.data.paidTRXnúmeroCosto total en TRX (incluye tarifa de activación si la dirección no estaba activada)
detail.data.hashcadena | 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.delegateAddresscadenaDirección del pool que delegó la Energy
detail.data.energyenteroCantidad de Energy + margen (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
-Solicitud duplicada aún en procesamiento409
1004Saldo insuficiente403
5000Error interno del servidor500
5001Proveedor de Energy no disponible503
5002Proveedor de Energy no disponible503
5003Servicio de Energy no disponible503
5004No se alcanzó el mínimo del proveedor de Energy503

Límites de tasa

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

PeriodoLímiteDescripción
1 segundo50 solicitudesMáximo 50 solicitudes 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 la idempotencia para evitar el procesamiento de órdenes duplicadas. Cuando envía múltiples solicitudes idénticas, el sistema garantiza que la orden se procese solo una vez.

Cómo funciona la idempotencia

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

  • Marca de tiempo de la solicitud (ventana de 1 segundo)
  • Cantidad de Energy
  • Dirección del receptor
  • Clave API

A cada solicitud se le asigna una ventana de singularidad de 1 segundo. Para proteger el sistema de abusos y garantizar un procesamiento adecuado, las solicitudes con parámetros idénticos no se pueden enviar con una frecuencia mayor a una vez por segundo.

Comportamiento actual: El sistema protege automáticamente a los clientes de reintentos erróneos sobre Energy ya solicitada. Si accidentalmente envía la misma solicitud dos veces, no se le cobrará dos veces.

Proporcionar su propia clave

Puede tomar la idempotencia en sus propias manos enviando el encabezado X-Idempotency-Key. Cuando está presente, ese valor por sí solo decide si una solicitud es una repetición, y no se utiliza la combinación automática anterior. Cuando está ausente, nada cambia: el servidor deriva la clave por usted.

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

Una clave con cualquier otra forma (un UUID con guiones, base64, hexadecimal en mayúsculas) se rechaza con 400 antes de que se realice 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 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 devuelve 400 aquí.

Cómo formar la clave

Derívela de su clave API. Eso hace que el valor sea único para su cuenta, reproducible en un reintento e imposible de alcanzar 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 solicitud. Elíjalo una sola vez, cuando se cree la orden 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 sola 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 de nuevo e inicia una nueva orden.

No use un valor al que cualquiera pudiera llegar: 64 ceros, el resumen de una palabra fija. Las claves comparten un único espacio entre cuentas. Tal colisión nunca expone la orden de otra cuenta, pero su solicitud 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 Energy para la misma dirección, una tras otra. La clave automática no puede distinguir eso de un reintento: las dos solicitudes 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 solicitudesQué sucede
Dentro de la misma ventana de 1 segundoLa segunda solicitud se toma como una repetición. No se ejecuta: obtiene 208 y la respuesta de la primera orden, incluido el orderId. No se cobra nada por ella
Con más de un segundo de diferenciaDos claves diferentes — ambas órdenes se realizan 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 realizó.

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

Su propia clave elimina las suposiciones, porque la decisión pasa al único lado que sabe la respuesta:

Qué está haciendoQué envíaResultado
Una segunda orden genuinamente nuevaUn nuevo nonceUna nueva clave — la orden se realiza
Un reintento de una orden cuyo resultado desconoceEl nonce del primer intentoLa misma clave — 208, la respuesta original, ningún segundo cargo

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 solicitudes duplicadas

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

Solicitud duplicada - Ya procesada (208)

Cuando se recibe una solicitud 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é.

Solicitud duplicada - Aún en procesamiento (409)

Cuando llega una solicitud 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": "b9e67b2412d33c92...",
    "retry_after_seconds": 3
}

Recomendación: Espere el tiempo especificado en retry_after_seconds antes de verificar el estado de la orden.

Buenas prácticas

  • No envíe solicitudes paralelas con los mismos parámetros: espere cada respuesta
  • Utilice un nuevo nonce para cada nueva orden, y el nonce del primer intento para cada reintento de la misma
  • Nunca reconstruya el nonce en el momento del envío: 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 realizó

Notas

  • La Energy 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, típicamente responde en hasta 2 segundos
  • Activación de dirección: Si la dirección del receptor no está activada, Netts la activa a precio de costo
  • Demora de activación: Para direcciones no activadas, la respuesta de la API puede tardar 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 Energy: 61,000 unidades
  • Cantidad máxima de Energy: 3,000,000 unidades por orden
  • Margen de Energy: +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 proveedor: Automática basada en costo y disponibilidad
  • Formato de ID de orden: 1H{request_id} para seguimiento unificado
  • Precios: Dinámicos según la hora del día y la cantidad de Energy
  • Duración: Fija de 1 hora (3600 segundos)
  • Límite de tasa: 50 solicitudes por segundo por dirección IP