Appearance
GET /apiv2/pricing
Endpoint universal de preços que retorna todos os preços de serviços em uma única resposta com períodos de tempo dinâmicos.
O preço pode mudar durante o atendimento
O preço retornado por este endpoint pode mudar enquanto um pedido está sendo processado. Um provedor de energy pode recusar uma solicitação de delegação; nesse caso, a Netts encaminha o pedido automaticamente para o próximo provedor disponível. A Netts tem o compromisso não apenas de oferecer o preço mais competitivo, mas também de garantir um fornecimento confiável de energy — portanto, um pedido pode ser atendido por um preço mais alto do que o cotado. Isso se aplica apenas a pedidos de 300.000 unidades de energy ou mais.
Recomendado
Este é o endpoint de preços recomendado. Ele substitui o endpoint legado /apiv2/prices, que será descontinuado.
URL do endpoint
GET https://netts.io/apiv2/pricingCabeçalhos da requisição
| Header | Obrigatório | Descrição | Valores |
|---|---|---|---|
| X-API-KEY | Sim | Sua chave de API | string |
| X-Real-IP | Sim | Endereço IP da lista de permissões | Endereço IP |
| X-Format | Não | Formato da resposta (padrão: JSON completo) | now, compact, short, short1h, count |
Parâmetros de consulta
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| services | string | all | Filtro separado por vírgulas de serviços a serem incluídos |
Serviços Disponíveis
| Serviço | Descrição |
|---|---|
energy_1h | Preços de delegação de energy de 1 hora |
energy_5m | Preços de delegação de energy de 5 minutos |
host | Tarifas de delegação de energy para Host |
aml | Preços de verificação de endereço AML |
bandwidth | Preços de aluguel de Bandwidth — opcional (opt-in): retornado apenas quando solicitado explicitamente via ?services=bandwidth (não faz parte da resposta padrão) |
Exemplos de Requisições
cURL — Resposta Completa
bash
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 Serviços
bash
# Apenas preços de energy 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"
# Energy 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"
# Apenas preços 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"
# Preços de aluguel de Bandwidth (opt-in — deve ser solicitado explicitamente)
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
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 Serviços
python
params = {"services": "energy_1h,aml"}
response = requests.get(url, headers=headers, params=params)Estrutura da Resposta
Campos de Nível Superior
| Campo | Tipo | Descrição |
|---|---|---|
| success | boolean | true para requisições bem-sucedidas |
| version | string | Versão da API (ex.: "2.1") |
| timestamp | string | Horário do servidor em ISO 8601 UTC |
| data | object | Carga útil da resposta |
Campos de Data
| Campo | Tipo | Descrição |
|---|---|---|
| data.trx_rate_usd | number | Taxa de câmbio TRX/USD atual |
| data.units_meta | object | Informações legíveis por máquina para conversão de unidades |
| data.services | object | Mapeamento dos serviços solicitados com dados de preços |
Units Meta
Permite que clientes convertam entre unidades programaticamente:
json
{
"units_meta": {
"sun": {"base": "trx", "multiplier": 1000000},
"trx": {"base": "trx", "multiplier": 1},
"usdt": {"base": "usdt", "multiplier": 1}
}
}Para converter de SUN para TRX: trx_price = sun_price / units_meta.sun.multiplier
Campos Comuns de Serviço
Cada serviço inclui estes campos:
| Campo | Tipo | Descrição |
|---|---|---|
| unit | string | Unidade de preço (sun, trx, usdt) |
| pricing_type | string | Como fazer o parsing deste serviço (veja abaixo) |
| description | string | Descrição legível por humanos |
| cache_ttl | integer | Frequência de atualização destes dados (segundos) |
Tipos de Precificação
O campo pricing_type informa aos clientes como fazer o parsing de cada serviço:
| Tipo | Estrutura | Usado por |
|---|---|---|
periodic | Array periods[] com preços baseados em horários | energy_1h, energy_5m |
flat_rates | Objeto rates{} com chaves de tarifas nomeadas | host |
provider_based | Objeto providers{} com dados de provedores | aml |
tiered_by_amount_and_period | tiers[] por faixa de valor, cada uma com periods[] | bandwidth |
Serviço: energy_1h / energy_5m
pricing_type: periodic
| Campo | Tipo | Descrição |
|---|---|---|
| current_period | string | Slug do período atualmente ativo |
| periods[] | array | Todos os períodos de precificação (dinâmicos, carregados do banco de dados) |
| periods[].id | string | Identificador único do período (slug) |
| periods[].label | string | Nome do período legível por humanos |
| periods[].start | string | Horário de início do período (HH:MM UTC) |
| periods[].end | string | Horário de término do período (HH:MM UTC) |
| periods[].is_current | boolean | Se este período está ativo no momento |
| periods[].price | integer | Preço por unidade de energy em SUN |
| periods[].tiers | array|null | Faixas de preço baseadas em volume (veja Faixas) |
Períodos dinâmicos
A quantidade de períodos, seus intervalos de tempo, rótulos e preços são totalmente dinâmicos e gerenciados no lado do servidor. Não fixe IDs ou contagens de períodos no código. Sempre itere sobre o array periods.
Serviço: host
pricing_type: flat_rates
| Campo | Tipo | Descrição |
|---|---|---|
| rates.standard_65k | number | Tarifa padrão para 65k de energy (TRX) |
| rates.standard_131k_initial | number | Tarifa padrão para 131k de energy, ativação inicial (TRX) |
| rates.frequent_65k | number | Tarifa frequente para 65k de energy (TRX) |
| rates.frequent_131k | number | Tarifa frequente para 131k de energy (TRX) |
Serviço: aml
pricing_type: provider_based
| Campo | Tipo | Descrição |
|---|---|---|
| providers | object | Mapeamento de provedores AML (dinâmico, pode mudar) |
| providers[name].price | number | Preço de verificação em USDT |
| providers[name].price_trx | number | Preço de verificação convertido para TRX na taxa atual |
| providers[name].available | boolean | Se o provedor possui cota disponível |
Provedores dinâmicos
Os provedores AML são carregados a partir do banco de dados. Novos provedores podem surgir ou os existentes podem ficar indisponíveis. Sempre itere sobre o objeto providers.
Serviço: bandwidth
pricing_type: tiered_by_amount_and_period
Opt-in e acesso
O preço de Bandwidth é retornado apenas quando solicitado explicitamente via ?services=bandwidth — ele não faz parte da resposta padrão. O próprio endpoint de aluguel de Bandwidth está disponível mediante solicitação; entre em contato com o suporte para obter acesso. Consulte Aluguel de Bandwidth.
O preço de aluguel de Bandwidth depende da quantidade do pedido (faixa da unidade), do período de aluguel (ex.: 5m / 1h), da janela de horário do dia (UTC) e do dia da semana. Os preços base são em SUN por unidade; além da base, sobretaxas fixas (em TRX) podem ser aplicadas — todos os valores são retornados na resposta.
A resposta fornece tanto uma visualização de conveniência (tiers — preços para a janela/dia atual) quanto a grade completa (windows + schedule — todas as janelas ao longo de todos os dias da semana).
Formato adaptativo — não fixe valores no código
A grade de preços é totalmente orientada a dados e pode mudar a qualquer momento: o número de janelas de tempo, seus rótulos, seus horários de início/fim, o conjunto de períodos de aluguel (novos períodos podem ser adicionados ou removidos), as faixas de quantidade, a divisão por dias da semana e os próprios preços. Os clientes devem iterar sobre os arrays retornados (windows, schedule, tiers, periods) e fazer a correspondência por valor — nunca presuma uma contagem fixa, rótulos fixos, horários fixos ou IDs de períodos fixos. O código escrito dessa forma continua funcionando quando o cronograma muda.
| Campo | Tipo | Descrição |
|---|---|---|
| unit | string | sun_per_unit |
| window | string | Rótulo da janela de horário do dia atual (UTC) |
| current_day_of_week | integer | Dia da semana atual, ISO 1=Seg … 7=Dom (UTC) |
| tiers[] | array | Faixas de quantidade para a janela/dia atual (conveniência; mesma estrutura de dentro de schedule) |
| windows[] | array | Diretório de todas as janelas de horário do dia (pode aumentar/diminuir/mudar) |
| windows[].label | string | Rótulo da janela |
| windows[].start / .end | string | Início/fim da janela HH:MM UTC (uma janela pode cruzar a meia-noite, ou seja, início > fim) |
| schedule[] | array | Grade completa — uma entrada por (dia da semana × janela) |
| schedule[].day_of_week | integer | Dia da semana ISO 1…7 |
| schedule[].window | string | Rótulo da janela (corresponde a um windows[].label) |
| schedule[].period_start / .period_end | string | HH:MM UTC |
| schedule[].is_current | boolean | true para o segmento ativo neste momento |
| schedule[].tiers[] | array | Faixas de quantidade para este segmento |
| tiers[].amount_min | integer | Limite inferior da faixa (inclusivo) |
| tiers[].amount_max | integer|null | Limite superior da faixa (exclusivo). null = ilimitado |
| tiers[].periods[] | array | Preços por período de aluguel dentro da faixa |
| tiers[].periods[].id | string | ID do período de aluguel (ex.: 5m, 1h) — pode mudar/expandir |
| tiers[].periods[].rental_seconds | integer | Duração do período em segundos |
| tiers[].periods[].price | integer | Preço por unidade de Bandwidth em SUN |
| surcharges | object | Adições fixas ao preço do cliente (TRX) — veja abaixo |
| limits | object | Limites do pedido: min_units, max_units |
Sobretaxas
| Campo | Tipo | Descrição |
|---|---|---|
| surcharges.small_order_threshold_units | integer | Pedidos com amount abaixo deste valor recebem a sobretaxa de pedido pequeno |
| surcharges.small_order_surcharge_trx | number | Adicionado (TRX) para pedidos pequenos de delegação — compensação por delegação on-chain + recuperação |
| surcharges.trx_send_surcharge_trx | number | Adicionado (TRX) quando o pedido é atendido enviando TRX — compensação pela transferência de TRX |
Exemplo de Resposta
json
{
"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}
}
}O schedule contém uma entrada para cada combinação (dia da semana × janela) — itere sobre ele para renderizar um calendário de preços completo. Exatamente uma entrada tem is_current: true.
Lógica do Cliente (calcular o preço do pedido)
Use tiers para "o preço neste momento". Para consultar um preço para outro horário, escolha a entrada correspondente do schedule por dia da semana + a janela cujo intervalo [period_start, period_end) contenha o horário (lembre-se de que uma janela pode cruzar a meia-noite quando start > end), e então use suas tiers.
# price for the current moment:
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: # match by value, not by index
base_trx = (p.price / units_meta.sun.multiplier) * amount
if amount < surcharges.small_order_threshold_units:
base_trx += surcharges.small_order_surcharge_trx # delegation orders
# TRX-send fulfillment branch instead:
# trx_branch_trx = base_trx_for_smallest_tier_shortest_period + surcharges.trx_send_surcharge_trx
# price for an arbitrary weekday/time: same logic, but first select the schedule[] entry
# where day_of_week matches and the time falls in [period_start, period_end).Centralizado e dinâmico
Preços de Bandwidth, janelas, divisão por dia da semana e sobretaxas são gerenciados no lado do servidor (banco de dados) e podem mudar. Sempre itere sobre windows, schedule, tiers e periods a partir da resposta e faça a correspondência por valor — não fixe contagens, rótulos, horários ou IDs de período no código. Acréscimos (markups) de subusuários não se aplicam a Bandwidth.
Faixas
Atualmente, tiers é null para todos os períodos. Quando o preço baseado em volume for ativado, o campo conterá um array de objetos de faixa:
json
{
"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 Faixas
| Campo | Tipo | Descrição |
|---|---|---|
| min_energy | integer | Quantidade mínima de energy para esta faixa (inclusivo) |
| max_energy | integer|null | Quantidade máxima de energy para esta faixa (inclusivo). null = ilimitado |
| price | integer | Preço por unidade de energy em SUN para esta faixa |
| label | string | Identificador da faixa |
Lógica do Cliente
if tiers != null:
find the tier where min_energy <= order_amount <= max_energy
use that tier's price
else:
use the flat price field for all order amountsFormatos de Resposta Compactos
Use o header X-Format para obter respostas de texto compactas. Elas retornam o preço do período ativo atual de energy_1h.
X-Format: now / compact / short
bash
curl -H "X-API-KEY: your_key" -H "X-Format: now" https://netts.io/apiv2/pricingtext
<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
O mesmo, mas sem o rótulo do período e o preço por unidade.
bash
curl -H "X-API-KEY: your_key" -H "X-Format: short1h" https://netts.io/apiv2/pricingtext
65k=<X.XXX> TRX (<X.XX>$), 131k=<X.XXX> TRX (<X.XX>$), 1m=<X.XXX> TRX (<X.XX>$)X-Format: count
Preços de pedidos em lote para 1, 2, 3, 5, 10, 20 pedidos.
bash
curl -H "X-API-KEY: your_key" -H "X-Format: count" https://netts.io/apiv2/pricingtext
1-<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_usdAcréscimo para Subusuários
Subusuários recebem automaticamente os preços com o acréscimo de sua conta principal aplicado. A API sempre retorna o preço final para o usuário autenticado — nenhum cálculo no lado do cliente é necessário.
Respostas de Erro
Os erros podem ter origem em duas camadas com formatos diferentes. Seu cliente deve tratar ambos.
Erros de Aplicação (da API)
Erros no nível da aplicação usam o formato padrão success/error:
Serviço Inválido (400)
json
{
"success": false,
"error": {
"code": 4002,
"message": "Unknown services: invalid_service"
}
}Erro de Autenticação (401)
Retornado pela aplicação quando a chave de API está ausente ou o IP não está na lista de permissões:
json
{
"detail": {
"code": -1,
"msg": "Invalid API key or IP not in whitelist"
}
}Formato diferente
Erros de autenticação usam o formato nativo detail do FastAPI, e não a estrutura success/error. Isso ocorre porque o erro é gerado antes que a solicitação alcance a lógica da aplicação.
Usuário Não Encontrado (404)
json
{
"detail": {
"code": -1,
"msg": "User not found"
}
}Erro Interno do Servidor (500)
json
{
"success": false,
"error": {
"code": 5001,
"message": "Failed to retrieve pricing data"
}
}Erros de Gateway (do Kong)
Estes erros são retornados pelo gateway da API antes que a solicitação chegue à aplicação. Eles utilizam o formato próprio do Kong:
Limite de Taxa Excedido (429)
json
{
"message": "API rate limit exceeded"
}Gateway Timeout (504)
json
{
"message": "An invalid response was received from the upstream server"
}Referência de Códigos de Erro
| Código | Descrição | Status HTTP | Origem |
|---|---|---|---|
-1 | Chave de API não fornecida | 401 | App |
-1 | Chave de API inválida ou IP fora da lista de permissões | 401 | App |
-1 | Usuário não encontrado | 404 | App |
4002 | Serviço desconhecido no parâmetro ?services= | 400 | App |
5000 | Erro interno do servidor | 500 | App |
5001 | Falha ao recuperar dados de preços | 500 | App |
5002 | Dados de preço indisponíveis para o formato compacto | 500 | App |
- | Limite de taxa da API excedido | 429 | Kong |
Tratamento de Erros Recomendado no Cliente
python
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}")Migração a partir de /apiv2/prices
| Aspecto | /apiv2/prices (antigo) | /apiv2/pricing (novo) |
|---|---|---|
| Períodos | 5 fixos | Dinâmicos a partir do banco de dados |
| Faixas de preço | 3 fixadas no código | Preço único + tiers futuros |
| Variações de duração | Não disponível | energy_5m |
| Preços de AML | Endpoint separado | Incluído via ?services=aml |
| Preços de Host | Misturados na resposta | Serviço host separado |
| Filtragem de serviços | Não disponível | Parâmetro ?services= |
| Conversão de unidades | Não documentado | units_meta na resposta |
| Informações de cache | Não documentado | cache_ttl por serviço |
| Formato da resposta | {"status": "success", ...} | {"success": true, "version": "2.1", "data": {...}} |
Limites de Taxa
Aplicam-se os mesmos limites de taxa do /apiv2/prices (configurados no gateway Kong).
Notas
- Todos os preços de energy estão em SUN — use
units_metapara conversão - Os preços de Host estão em TRX
- Os preços de AML estão em USDT com conversão para TRX incluída
- Todos os horários estão em UTC
- Use o
cache_ttlde cada serviço para saber com que frequência os dados são atualizados - Use
pricing_typepara determinar como fazer o parsing de cada serviço - Períodos, provedores, tarifas e todos os valores são dinâmicos — não os fixe no código
- O preço de Bandwidth é opcional (opt-in) (
?services=bandwidth), utilizatiered_by_amount_and_periodcomsurchargese não está sujeito ao acréscimo de subusuários