GET /apiv2/pricing
Endpoint de precios universal que devuelve todos los precios de los servicios en una sola respuesta con períodos de tiempo dinámicos.
El precio puede cambiar durante el procesamiento
El precio devuelto por este endpoint puede cambiar mientras se procesa una orden. Un proveedor de energía puede rechazar una solicitud de delegación, en cuyo caso Netts redirige automáticamente la orden al siguiente proveedor disponible. Netts se compromete no solo a ofrecer el precio más competitivo, sino también a garantizar un suministro de energía confiable; por lo tanto, una orden puede procesarse a un precio superior al cotizado. Esto se aplica únicamente a órdenes de 300,000 unidades de energía o más.
Recomendado
Este es el endpoint de precios recomendado. Reemplaza al endpoint heredado /apiv2/prices, que quedará obsoleto.
URL del endpoint
GET https://netts.io/apiv2/pricingEncabezados de solicitud
| Encabezado | Requerido | Descripción | Valores |
|---|---|---|---|
| X-API-KEY | Sí | Su clave API | string |
| X-Real-IP | Sí | Dirección IP de la lista blanca | Dirección IP |
| X-Format | No | Formato de respuesta (predeterminado: JSON completo) | now, compact, short, short1h, count |
Parámetros de consulta
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
| services | string | all | Filtro separado por comas de los servicios a incluir |
Servicios disponibles
| Servicio | Descripción |
|---|---|
energy_1h | Precios de delegación de energía de 1 hora |
energy_5m | Precios de delegación de energía de 5 minutos |
host | Tarifas de delegación de energía de host |
aml | Precios de verificación de direcciones AML |
bandwidth | Precios de alquiler de Bandwidth — opcional (opt-in): se devuelve solo cuando se solicita explícitamente a través de ?services=bandwidth (no forma parte de la respuesta predeterminada) |
Solicitudes de ejemplo
cURL — Respuesta completa
curl -X GET https://netts.io/apiv2/pricing \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip"cURL — Filtrar por servicios
# Solo precios de energía 1h
curl -X GET "https://netts.io/apiv2/pricing?services=energy_1h" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip"
# Energía 1h + AML
curl -X GET "https://netts.io/apiv2/pricing?services=energy_1h,aml" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip"
# Solo precios de host
curl -X GET "https://netts.io/apiv2/pricing?services=host" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip"
# Precios de alquiler de Bandwidth (opcional: debe solicitarse explícitamente)
curl -X GET "https://netts.io/apiv2/pricing?services=bandwidth" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip"Python
import requests
url = "https://netts.io/apiv2/pricing"
headers = {
"X-API-KEY": "your_api_key",
"X-Real-IP": "your_whitelisted_ip"
}
response = requests.get(url, headers=headers)
data = response.json()
if data.get("success"):
print(f"API version: {data['version']}")
print(f"TRX/USD rate: {data['data']['trx_rate_usd']}")
services = data["data"]["services"]
for svc_name, svc_data in services.items():
pricing_type = svc_data.get("pricing_type")
print(f"\n--- {svc_name} ({pricing_type}) ---")
if pricing_type == "periodic":
for period in svc_data["periods"]:
marker = " <-- current" if period["is_current"] else ""
print(f" {period['label']}: {period['price']} {svc_data['unit']}{marker}")
elif pricing_type == "flat_rates":
for rate, price in svc_data["rates"].items():
print(f" {rate}: {price} {svc_data['unit']}")
elif pricing_type == "provider_based":
for name, info in svc_data["providers"].items():
status = "available" if info["available"] else "unavailable"
print(f" {name}: {info['price']} {svc_data['unit']} - {status}")Python — Filtrar servicios
params = {"services": "energy_1h,aml"}
response = requests.get(url, headers=headers, params=params)Estructura de la respuesta
Campos de nivel superior
| Campo | Tipo | Descripción |
|---|---|---|
| success | boolean | true para solicitudes exitosas |
| version | string | Versión de la API (p. ej., "2.1") |
| timestamp | string | Hora del servidor en ISO 8601 UTC |
| data | object | Carga útil de la respuesta |
Campos de datos
| Campo | Tipo | Descripción |
|---|---|---|
| data.trx_rate_usd | number | Tipo de cambio actual TRX/USD |
| data.units_meta | object | Información legible por máquina para la conversión de unidades |
| data.services | object | Mapa de servicios solicitados con datos de precios |
Metadatos de unidades
Permite a los clientes convertir entre unidades mediante programación:
{
"units_meta": {
"sun": {"base": "trx", "multiplier": 1000000},
"trx": {"base": "trx", "multiplier": 1},
"usdt": {"base": "usdt", "multiplier": 1}
}
}Para convertir de SUN a TRX: trx_price = sun_price / units_meta.sun.multiplier
Campos comunes del servicio
Cada servicio incluye estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
| unit | string | Unidad de precio (sun, trx, usdt) |
| pricing_type | string | Cómo analizar este servicio (ver a continuación) |
| description | string | Descripción legible por humanos |
| cache_ttl | integer | Frecuencia de actualización de estos datos (segundos) |
Tipos de fijación de precios
El campo pricing_type indica a los clientes cómo analizar cada servicio:
| Tipo | Estructura | Utilizado por |
|---|---|---|
periodic | Matriz periods[] con precios basados en tiempo | energy_1h, energy_5m |
flat_rates | Objeto rates{} con claves de tarifas con nombre | host |
provider_based | Objeto providers{} con datos del proveedor | aml |
tiered_by_amount_and_period | tiers[] por rango de cantidad, cada uno con periods[] | bandwidth |
Servicio: energy_1h / energy_5m
pricing_type: periodic
| Campo | Tipo | Descripción |
|---|---|---|
| current_period | string | Slug del período actualmente activo |
| periods[] | array | Todos los períodos de precios (dinámicos, cargados desde la base de datos) |
| periods[].id | string | Identificador único de período (slug) |
| periods[].label | string | Nombre del período legible por humanos |
| periods[].start | string | Hora de inicio del período (HH:MM UTC) |
| periods[].end | string | Hora de fin del período (HH:MM UTC) |
| periods[].is_current | boolean | Si este período está actualmente activo |
| periods[].price | integer | Precio por unidad de energía en SUN |
| periods[].tiers | array|null | Niveles de precios basados en volumen (ver Niveles) |
Períodos dinámicos
El número de períodos, sus rangos de tiempo, etiquetas y precios son completamente dinámicos y se gestionan del lado del servidor. No codifique de forma rígida los ID ni la cantidad de períodos. Itere siempre sobre la matriz periods.
Servicio: host
pricing_type: flat_rates
| Campo | Tipo | Descripción |
|---|---|---|
| rates.standard_65k | number | Tarifa estándar para 65k de energía (TRX) |
| rates.standard_131k_initial | number | Tarifa estándar para 131k de energía, activación inicial (TRX) |
| rates.frequent_65k | number | Tarifa frecuente para 65k de energía (TRX) |
| rates.frequent_131k | number | Tarifa frecuente para 131k de energía (TRX) |
Servicio: aml
pricing_type: provider_based
| Campo | Tipo | Descripción |
|---|---|---|
| providers | object | Mapa de proveedores de AML (dinámico, puede cambiar) |
| providers[name].price | number | Precio de verificación en USDT |
| providers[name].price_trx | number | Precio de verificación convertido a TRX al tipo de cambio actual |
| providers[name].available | boolean | Si el proveedor tiene cuota disponible |
Proveedores dinámicos
Los proveedores de AML se cargan desde la base de datos. Pueden aparecer nuevos proveedores o los existentes pueden dejar de estar disponibles. Itere siempre sobre el objeto providers.
Servicio: bandwidth
pricing_type: tiered_by_amount_and_period
Acceso y activación opcional (opt-in)
Los precios de Bandwidth se devuelven únicamente cuando se solicitan de forma explícita mediante ?services=bandwidth; no forman parte de la respuesta predeterminada. El endpoint de alquiler de Bandwidth en sí está disponible a petición; contacte al soporte para obtener acceso. Consulte Bandwidth rental.
El precio del alquiler de Bandwidth depende del monto de la orden (nivel de unidades), el período de alquiler (p. ej., 5m / 1h), la ventana horaria del día (UTC) y el día de la semana. Los precios base están en SUN por unidad; por encima de la base, se pueden aplicar recargos fijos (en TRX) — todos los valores se devuelven en la respuesta.
La respuesta proporciona tanto una vista práctica (tiers — precios para la ventana/día actual) como la cuadrícula completa (windows + schedule — cada ventana en cada día de la semana).
Formato adaptable — no codificar de forma rígida
La cuadrícula de precios está completamente basada en datos y puede cambiar en cualquier momento: el número de ventanas horarias, sus etiquetas, sus horas de inicio/fin, el conjunto de períodos de alquiler (se pueden agregar o eliminar nuevos períodos), los niveles de montos, el desglose por día de la semana y los precios en sí. Los clientes deben iterar sobre las matrices devueltas (windows, schedule, tiers, periods) y hacer coincidir por valor; nunca asuma una cantidad fija, etiquetas fijas, horas fijas o identificadores de períodos fijos. El código escrito de esta manera seguirá funcionando cuando cambie el cronograma.
| Campo | Tipo | Descripción |
|---|---|---|
| unit | string | sun_per_unit |
| window | string | Etiqueta de la ventana horaria actual (UTC) |
| current_day_of_week | integer | Día de la semana actual, ISO 1=Lun … 7=Dom (UTC) |
| tiers[] | array | Niveles de cantidad para la ventana/día actual (práctica; misma estructura que dentro de schedule) |
| windows[] | array | Directorio de todas las ventanas horarias del día (puede crecer/reducirse/desplazarse) |
| windows[].label | string | Etiqueta de la ventana |
| windows[].start / .end | string | Inicio/fin de la ventana HH:MM UTC (una ventana puede cruzar la medianoche, es decir, start > end) |
| schedule[] | array | Cuadrícula completa — una entrada por cada combinación de (día de la semana × ventana) |
| schedule[].day_of_week | integer | Día de la semana ISO 1…7 |
| schedule[].window | string | Etiqueta de la ventana (coincide con una windows[].label) |
| schedule[].period_start / .period_end | string | HH:MM UTC |
| schedule[].is_current | boolean | true para el segmento activo en este momento |
| schedule[].tiers[] | array | Niveles de cantidad para este segmento |
| tiers[].amount_min | integer | Límite inferior del nivel (inclusive) |
| tiers[].amount_max | integer|null | Límite superior del nivel (exclusivo). null = ilimitado |
| tiers[].periods[] | array | Precios por período de alquiler dentro del nivel |
| tiers[].periods[].id | string | Identificador del período de alquiler (p. ej., 5m, 1h) — puede cambiar/extenderse |
| tiers[].periods[].rental_seconds | integer | Duración del período en segundos |
| tiers[].periods[].price | integer | Precio por unidad de Bandwidth en SUN |
| surcharges | object | Adiciones fijas al precio del cliente (TRX) — ver a continuación |
| limits | object | Límites de la orden: min_units, max_units |
Recargos
| Campo | Tipo | Descripción |
|---|---|---|
| surcharges.small_order_threshold_units | integer | Las órdenes con amount por debajo de este valor reciben el recargo por orden pequeña |
| surcharges.small_order_surcharge_trx | number | Añadido (TRX) para órdenes pequeñas de delegación — compensación por delegación on-chain + recuperación |
| surcharges.trx_send_surcharge_trx | number | Añadido (TRX) cuando la orden se procesa mediante envío de TRX — compensación por la transferencia de TRX |
Respuesta de ejemplo
{
"bandwidth": {
"unit": "sun_per_unit",
"pricing_type": "tiered_by_amount_and_period",
"description": "Bandwidth delegation rental",
"cache_ttl": 30,
"window": "<current window label>",
"current_day_of_week": 7,
"tiers": [
{
"amount_min": 400,
"amount_max": 1000,
"periods": [
{"id": "5m", "rental_seconds": 300, "price": "<price_sun>"},
{"id": "1h", "rental_seconds": 3600, "price": "<price_sun>"}
]
},
{"amount_min": 1000, "amount_max": 3000, "periods": ["..."]},
{"amount_min": 3000, "amount_max": null, "periods": ["..."]}
],
"windows": [
{"label": "<window label>", "start": "01:00", "end": "09:00"},
{"label": "<window label>", "start": "14:00", "end": "00:00"}
],
"schedule": [
{
"day_of_week": 1,
"window": "<window label>",
"period_start": "01:00",
"period_end": "09:00",
"is_current": false,
"tiers": [
{"amount_min": 400, "amount_max": 1000, "periods": [
{"id": "5m", "rental_seconds": 300, "price": "<price_sun>"},
{"id": "1h", "rental_seconds": 3600, "price": "<price_sun>"}
]}
]
}
],
"surcharges": {
"small_order_threshold_units": 1000,
"small_order_surcharge_trx": "<trx>",
"trx_send_surcharge_trx": "<trx>"
},
"limits": {"min_units": 400, "max_units": 5000}
}
}schedule contiene una entrada para cada combinación de (día de la semana × ventana) — itere sobre ella para generar un calendario de precios completo. Exactamente una entrada tiene is_current: true.
Lógica del cliente (calcular el precio de la orden)
Utilice tiers para "el precio en este momento". Para consultar el precio de otro horario, elija la entrada coincidente de schedule por día de la semana + la ventana cuyo [period_start, period_end) contenga la hora (recuerde que una ventana puede cruzar la medianoche cuando start > end), luego utilice sus tiers.
# precio para el momento actual:
for tier in bandwidth.tiers:
if tier.amount_min <= amount < (tier.amount_max or infinity):
for p in tier.periods:
if p.id == requested_period: # coincidir por valor, no por índice
base_trx = (p.price / units_meta.sun.multiplier) * amount
if amount < surcharges.small_order_threshold_units:
base_trx += surcharges.small_order_surcharge_trx # órdenes de delegación
# rama de cumplimiento mediante envío de TRX en su lugar:
# trx_branch_trx = base_trx_for_smallest_tier_shortest_period + surcharges.trx_send_surcharge_trx
# precio para un día de la semana/hora arbitrario: misma lógica, pero primero seleccione la entrada schedule[]
# donde coincida day_of_week y la hora caiga dentro de [period_start, period_end).Centralizado y dinámico
Los precios de Bandwidth, las ventanas, el desglose por día de la semana y los recargos se gestionan del lado del servidor (DB) y pueden cambiar. Siempre itere sobre windows, schedule, tiers y periods de la respuesta y haga coincidir por valor; no codifique de forma fija recuentos, etiquetas, horas o identificadores de períodos. Los márgenes de SUB-usuarios no se aplican a Bandwidth.
Niveles
Actualmente tiers es null para todos los períodos. Cuando se habilita la fijación de precios basada en volumen, el campo contendrá una matriz de objetos de nivel:
{
"tiers": [
{
"min_energy": 0,
"max_energy": 64999,
"price": "<price_sun>",
"label": "standard"
},
{
"min_energy": 65000,
"max_energy": 130999,
"price": "<price_sun>",
"label": "65k"
},
{
"min_energy": 131000,
"max_energy": 131000,
"price": "<price_sun>",
"label": "131k"
},
{
"min_energy": 131001,
"max_energy": null,
"price": "<price_sun>",
"label": "bulk"
}
]
}Esquema de niveles
| Campo | Tipo | Descripción |
|---|---|---|
| min_energy | integer | Cantidad mínima de energía para este nivel (inclusive) |
| max_energy | integer|null | Cantidad máxima de energía para este nivel (inclusive). null = ilimitado |
| price | integer | Precio por unidad de energía en SUN para este nivel |
| label | string | Identificador del nivel |
Lógica del cliente
if tiers != null:
encontrar el nivel donde min_energy <= order_amount <= max_energy
usar el precio de ese nivel
else:
usar el campo de precio fijo para todas las cantidades de órdenesFormatos de respuesta compactos
Utilice el encabezado X-Format para obtener respuestas de texto compactas. Estas devuelven el precio del período activo actual de energy_1h.
X-Format: now / compact / short
curl -H "X-API-KEY: your_key" -H "X-Format: now" https://netts.io/apiv2/pricing<Period>: price=<N> sun, 65k=<X.XXX> TRX (<X.XX>$), 131k=<X.XXX> TRX (<X.XX>$), 1m=<X.XXX> TRX (<X.XX>$)X-Format: short1h
Igual pero sin la etiqueta del período ni el precio por unidad.
curl -H "X-API-KEY: your_key" -H "X-Format: short1h" https://netts.io/apiv2/pricing65k=<X.XXX> TRX (<X.XX>$), 131k=<X.XXX> TRX (<X.XX>$), 1m=<X.XXX> TRX (<X.XX>$)X-Format: count
Precios de órdenes al por mayor para 1, 2, 3, 5, 10, 20 órdenes.
curl -H "X-API-KEY: your_key" -H "X-Format: count" https://netts.io/apiv2/pricing1-<X.XXX> TRX (<X.XX>$), 2-<X.XXX> TRX (<X.XX>$), ...Fórmula de cálculo
TRX cost = (price_sun / units_meta.sun.multiplier) x energy_amount
USD cost = TRX_cost x trx_rate_usdMargen de SUB-usuarios
Los SUB-usuarios reciben automáticamente precios con el margen de su cuenta principal aplicado. La API siempre devuelve el precio final para el usuario autenticado; no se necesita ningún cálculo por parte del cliente.
Respuestas de error
Los errores pueden provenir de dos capas con diferentes formatos. Su cliente debe manejar ambos.
Errores de aplicación (desde la API)
Los errores a nivel de aplicación utilizan el formato estándar success/error:
Servicio inválido (400)
{
"success": false,
"error": {
"code": 4002,
"message": "Unknown services: invalid_service"
}
}Error de autenticación (401)
Devuelto por la aplicación cuando falta la clave API o la IP no está en la lista blanca:
{
"detail": {
"code": -1,
"msg": "Invalid API key or IP not in whitelist"
}
}Formato diferente
Los errores de autenticación utilizan el formato nativo detail de FastAPI, no la estructura success/error. Esto se debe a que el error se genera antes de que la solicitud llegue a la lógica de la aplicación.
Usuario no encontrado (404)
{
"detail": {
"code": -1,
"msg": "User not found"
}
}Error interno del servidor (500)
{
"success": false,
"error": {
"code": 5001,
"message": "Failed to retrieve pricing data"
}
}Errores de gateway (desde Kong)
Estos errores son devueltos por el gateway de la API antes de que la solicitud llegue a la aplicación. Utilizan el formato propio de Kong:
Límite de tasa excedido (429)
{
"message": "API rate limit exceeded"
}Tiempo de espera del gateway agotado (504)
{
"message": "An invalid response was received from the upstream server"
}Referencia de códigos de error
| Código | Descripción | Estado HTTP | Origen |
|---|---|---|---|
-1 | Clave API no proporcionada | 401 | App |
-1 | Clave API inválida o IP no incluida en la lista blanca | 401 | App |
-1 | Usuario no encontrado | 404 | App |
4002 | Servicio desconocido en el parámetro ?services= | 400 | App |
5000 | Error interno del servidor | 500 | App |
5001 | Error al recuperar datos de precios | 500 | App |
5002 | Datos de precios no disponibles para el formato compacto | 500 | App |
- | Límite de tasa de la API excedido | 429 | Kong |
Manejo de errores recomendado en el cliente
response = requests.get(url, headers=headers)
data = response.json()
if response.status_code == 200 and data.get("success"):
# Success — process data
services = data["data"]["services"]
elif response.status_code == 429:
# Kong rate limit — back off and retry
retry_after = response.headers.get("Retry-After", "60")
time.sleep(int(retry_after))
elif "detail" in data:
# FastAPI auth/validation error
detail = data["detail"]
if isinstance(detail, dict):
print(f"Error {detail.get('code')}: {detail.get('msg')}")
else:
print(f"Error: {detail}")
elif "error" in data:
# Application error
err = data["error"]
print(f"Error {err.get('code')}: {err.get('message')}")
else:
print(f"Unexpected response: {response.status_code}")Migración desde /apiv2/prices
| Aspecto | /apiv2/prices (antiguo) | /apiv2/pricing (nuevo) |
|---|---|---|
| Períodos | 5 fijos | Dinámicos desde la BD |
| Niveles de precio | 3 codificados de forma rígida | Precio único + futuros tiers |
| Variantes de duración | No disponible | energy_5m |
| Precios de AML | Endpoint separado | Incluido mediante ?services=aml |
| Precios de host | Mezclados en la respuesta | Servicio host separado |
| Filtrado de servicios | No disponible | Parámetro ?services= |
| Conversión de unidades | No documentado | units_meta en la respuesta |
| Información de caché | No documentado | cache_ttl por servicio |
| Formato de respuesta | {"status": "success", ...} | {"success": true, "version": "2.1", "data": {...}} |
Límites de tasa
Se aplican los mismos límites de tasa que en /apiv2/prices (configurados en el gateway Kong).
Notas
- Todos los precios de energía están en SUN — use
units_metapara la conversión - Los precios de host están en TRX
- Los precios de AML están en USDT con la conversión a TRX incluida
- Todas las horas están en UTC
- Use
cache_ttlpor servicio para saber con qué frecuencia se actualizan los datos - Use
pricing_typepara determinar cómo analizar cada servicio - Los períodos, proveedores, tarifas y todos los valores son dinámicos — no los codifique de forma rígida
- La fijación de precios de Bandwidth es opcional (opt-in) (
?services=bandwidth), utilizatiered_by_amount_and_periodconsurchargesy no está sujeta al margen de SUB-usuarios