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

POST /apiv2/bandwidth ​

Аренда bandwidth в сети TRON и её делегирование на адрес получателя на фиксированный период: 5 минут, а для аккредитованных аккаунтов — 1 час.

⚠️ Уровни доступа.

  • Аккредитованные аккаунты могут арендовать любой объём (до 5000) на 5 минут или 1 час в пределах размера пула и максимальных лимитов, с поддержкой нескольких параллельных заказов. Аккредитация предоставляется поддержкой Netts.
  • Без аккредитации можно арендовать только 400 единиц на 5 минут, один раз — следующий заказ разрешён только после окончания предыдущей аренды. Запросы на объём, отличный от 400, на 1 час или второй заказ при активном первом будут отклонены.

URL эндпоинта ​

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

Заголовки запроса ​

ЗаголовокОбязательныйОписание
Content-TypeДаapplication/json
X-API-KEYДаВаш API-ключ из панели управления Netts
X-Real-IPДаIP-адрес из вашего белого списка
X-Idempotency-KeyНетНеобязательный сгенерированный клиентом ключ (base64) для безопасного повтора запроса без дублирования заказа. Если не передан, сервер сгенерирует его автоматически

Тело запроса ​

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

Параметры ​

ПараметрТипОбязательныйОписание
amountintegerДаКоличество единиц Bandwidth для аренды (минимум: 400, максимум: 5000)
receiveAddressstringДаАдрес TRON, который получит bandwidth (T…, 34 символа, base58)
periodstringДаДлительность аренды: "5m" (5 минут) или "1h" (1 час, только для аккредитованных аккаунтов)
trx_sendbooleanНетГарантированная транзакция: если bandwidth недоступна, на адрес вместо этого отправляется TRX, чтобы транзакция всё равно прошла. Работает только при amount = 400 (в остальных случаях игнорируется). По умолчанию false
checkbooleanНетЕсли true и у получателя уже есть более 400 bandwidth, заказ не делегируется и средства не списываются (статус enough). По умолчанию false
testbooleanНетТестовый запуск. Если true, имитируется полный цикл выполнения заказа — ответ сообщает результат, который был бы получен, и цену, которая была бы списана — без каких-либо действий в блокчейне и без списания средств. По умолчанию false

Примеры запросов ​

Приведённые ниже примеры также формируют и отправляют заголовок X-Idempotency-Key, чтобы случайный повтор не создал второй заказ. Полные правила см. в разделе Идемпотентность.

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

Полный пример клиента (Python + cURL) включён в пакет сервиса (handler_bandwidth/doc/client_example/).

Ответ ​

Успешно — bandwidth делегирована (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"
        }
    }
}

Успешно — вместо bandwidth отправлены TRX (200 OK, только amount=400 + trx_send=true) ​

Когда в пуле нет bandwidth и включён параметр trx_send, на адрес отправляются TRX, чтобы транзакция всё равно прошла. В этом случае применяется фиксированная оплата независимо от запрошенного периода.

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

Уже достаточно — средства не списаны (200 OK, только с check=true) ​

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

В обработке — внешний провайдер (202 Accepted) ​

Возвращается, когда заказ асинхронно передан внешнему поставщику. Опрашивайте status endpoint (ниже), используя orderId, пока он не завершится.

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

Тестовый запуск (200 OK, только с test=true) ​

Имитируется весь процесс заказа. testAction сообщает, что было бы выполнено, а wouldCostTRX — сколько было бы списано. Ничего не делегируется, TRX не отправляются, средства не списываются (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
        }
    }
}

Значения testAction: would_delegate (bandwidth была бы делегирована), would_trx_send (нет bandwidth, amount=400 + trx_send → были бы отправлены TRX), enough (у получателя уже достаточно, при check=true) или would_error:<reason> (например, no_bandwidth, not_whitelisted).

Поля ответа ​

ПолеТипОписание
detail.codeinteger10000 делегировано/TRX, 10002 достаточно, 10001 в обработке
detail.statusstringcompleted / enough / processing / failed
detail.data.orderIdstringID заказа, формат B5M… (5м) / B1H… (1ч) — используйте его для status endpoint
detail.data.paidTRXnumberСписанная сумма в TRX (0 при enough)
detail.data.fulfilledBystringbandwidth (делегировано) / trx (отправлены TRX)
detail.data.hasharrayХеши транзакций делегирования (до 10). Всегда массив (пустой для ветки TRX)
detail.data.trxSendHasharrayХеш(и) перевода TRX, присутствует только при fulfilledBy = trx
detail.data.bandwidthintegerДелегированное количество единиц Bandwidth
detail.data.periodstringПериод аренды (5m / 1h)

Эндпоинт статуса ​

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

Заголовки: X-API-KEY + X-Real-IP (заказ должен принадлежать аутентифицированному пользователю).

Состояние заказаHTTPcodestatus
Завершён20010000completed (с hash / trxSendHash)
В процессе20010001processing
Уже достаточно20010002enough
Ошибка2005003failed
Не найден / не ваш404-1—

Эндпоинт отзыва ​

Добровольный отзыв (анделегирование) bandwidth одного из ваших делегированных заказов до истечения его срока действия. Bandwidth возвращается автоматически, и возвращается хеш транзакции.

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

Заголовки: X-API-KEY + X-Real-IP (заказ должен принадлежать аутентифицированному пользователю).

Состояние заказаHTTPcodestatusРезультат
Делегирован → отозван сейчас20010004reclaimedreclaimHash (хеши транзакций анделегирования)
Уже отозван20010004reclaimedreclaimHash + сообщение "already reclaimed"
Не в состоянии делегирования (нечего отзывать)4005005failed—
Отзыв ещё не завершён5035003failedповторите попытку позже
Не найден / не ваш404-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)}")

Стоимость аренды не возвращается при добровольном досрочном отзыве — отзыв лишь возвращает делегированную bandwidth обратно в пул раньше окончания периода.

Ответы с ошибками ​

Ошибка аутентификации (401) ​

json
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }

Недостаточно средств (403) ​

json
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient funds" } }

Ошибка валидации (400) ​

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

Ошибка делегирования / Сервис недоступен (503) ​

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

Справочник кодов ошибок ​

КодОписаниеHTTP-статус
10000Успешно (делегировано или отправлены TRX)200
10000Успешно (кэшированный ответ)208
10001Принято, обрабатывается внешним провайдером202
10002У получателя уже достаточно bandwidth (средства не списаны)200
10003Тестовый запуск — предварительный просмотр результата и цены, средства не списаны (test=true)200
10004Bandwidth отозвана (добровольное анделегирование) — возвращён reclaimHash200
-Дублирующий запрос всё ещё обрабатывается409
-1Недействительный API-ключ / IP не в белом списке401
1004Недостаточный баланс403
1005Нет адреса плательщика для пользователя400
5004Недопустимый объём/период (валидация)400
5005Нечего отзывать (заказ не находится в состоянии делегирования)400
5007Без аккредитации — только одна аренда единовременно; предыдущий заказ всё ещё активен (дождитесь его окончания)503
5008Без аккредитации — разрешены заказы только на 400 единиц на 5 минут; для больших объёмов или 1 часа требуется аккредитация503
5003Ошибка делегирования bandwidth / недоступно503
5000Внутренняя ошибка сервера500

Ограничения частоты запросов ​

ПериодЛимитОписание
1 секунда50 запросовМаксимум 50 запросов в секунду на один IP

Превышен лимит запросов (429) ​

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

Идемпотентность ​

Отправляйте необязательный заголовок X-Idempotency-Key, чтобы случайный повтор не создал второй заказ — исходный ответ возвращается со статусом HTTP 208. Если вы не передаёте заголовок, сервер автоматически формирует ключ на основе параметров вашего запроса в пределах короткого временного окна.

Как формировать ключ ​

Ключ представляет собой base64( HMAC-SHA256( secret, message ) ) — 44-символьную строку base64, где:

  • secret = ваш API-ключ (X-API-KEY);
  • message = поля, объединённые через : — receiveAddress:amount:period:nonce.

nonce — это любое значение, которое является неизменным при повторных попытках одного и того же логического заказа, но отличается для разных заказов — например, UUID, который вы сохраняете для этого заказа, или грубый временной интервал (timestamp bucket). Генерируйте ключ один раз на заказ и отправляйте ровно то же самое значение при каждой повторной попытке.

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
# затем отправьте его в виде заголовка:
-H "X-Idempotency-Key: <base64_key>"

Включение period в сообщение имеет важное значение: аренда на один и тот же адрес на 5 минут и на 1 час является разными заказами и должна порождать разные ключи.

Валидация. Переданный X-Idempotency-Key должен быть строкой base64 длиной от 16 до 64 символов (набор символов A–Z a–z 0–9 + / = _ -). Некорректный или слишком длинный ключ отклоняется с кодом HTTP 400 (code 5004).

Код состоянияЗначение
200Успешно обработано (первый запрос)
208Уже успешно обработано — возвращён кэшированный ответ (повторное списание не производится)
409Такой же запрос обрабатывается прямо сейчас — подождите, не повторяйте запрос сразу

Повтор после ошибки. Кэшируются только успешные результаты (completed / enough). Если предыдущая попытка завершилась ошибкой или по таймауту (средства не были списаны), вы можете безопасно повторить попытку с тем же X-Idempotency-Key — заказ будет выполнен заново вместо возврата старой ошибки. Пока попытка всё ещё находится в процессе выполнения, вы получите 409; подождите и повторите попытку.

Постоплатные аккаунты ​

Аккаунты с постоплатной системой расчётов используют тот же endpoint, URL, заголовки и тело запроса, что и все остальные. Разница заключается в способе оплаты заказа:

  • С вашего депозита ничего не списывается. Каждый выполненный заказ добавляется к сумме задолженности вашего аккаунта в валюте расчётов, согласованной в договоре. Вы оплачиваете её по счёту в соответствии с вашим соглашением.
  • У вашего аккаунта есть кредитный лимит. Пока сумма задолженности находится в пределах лимита, заказы принимаются даже при нулевом депозите. Аренда на 5 минут и на 1 час учитывается в рамках одного и того же лимита bandwidth.
  • Оплачиваются только фактически оказанные услуги: bandwidth, делегированная на адрес, или TRX, отправленные взамен (fulfilledBy = trx). Сумма такая же, как и для предоплатных заказов.
  • Заказ, который был отклонён, не выполнен, тестовый запуск (test: true) или заказ с ответом enough (check: true), ничего не стоит.
  • Добровольный досрочный отзыв не уменьшает сумму к оплате, аналогично предоплатным заказам.
  • Уровни доступа, объёмы, периоды и все остальные правила этого эндпоинта такие же, как и для предоплатных аккаунтов.

Постоплатная система расчётов подключается Netts для аккаунта по запросу. Каждый ответ сообщает, как оплачивается заказ: значение paymentMode равно postpaid или prepaid.

Проверка цены (test: true) ​

json
{
    "amount": 1000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "period": "5m",
    "test": true
}
json
{
    "detail": {
        "code": 10003,
        "status": "test",
        "msg": "Test run — no on-chain action, no charge",
        "data": {
            "orderId": "B5M1a2b3c4d5e6f70",
            "testAction": "would_delegate",
            "wouldCostTRX": 0.7,
            "paidTRX": 0,
            "bandwidth": 1000,
            "period": "5m",
            "receiverFreeBandwidth": 600,
            "paymentMode": "postpaid"
        }
    }
}

wouldCostTRX — это сумма в TRX, которая была бы добавлена к вашей задолженности. Ничего не делегируется и не тарифицируется.

Успешный заказ ​

json
{
    "detail": {
        "code": 10000,
        "status": "completed",
        "msg": "Successful, 0.700000 TRX, postpaid",
        "data": {
            "orderId": "B5M0f9e8d7c6b5a41",
            "paidTRX": 0.7,
            "fulfilledBy": "bandwidth",
            "hash": ["<txid>"],
            "bandwidth": 1000,
            "period": "5m",
            "paymentMode": "postpaid",
            "totalTRX": "0.700000"
        }
    }
}
ПолеОписание
paidTRXСтоимость услуги в TRX. Для постоплатных аккаунтов она не списывается с депозита
paymentModepostpaid
totalTRXТочная сумма, 6 знаков после запятой

Все остальные поля, включая ветку TRX (fulfilledBy = trx, trxSendHash), такие же, как и для предоплатных заказов.

Исчерпан кредитный лимит (402) ​

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

Заказ не выполняется и оплата не начисляется. Новые заказы снова начнут приниматься после поступления вашего платежа или увеличения лимита.

Коды ошибок постоплаты ​

КодHTTPОписание
1004402Исчерпан кредитный лимит постоплаты
5032503Цена временно недоступна
5034503Биллинг временно недоступен — заказ не был принят
5036503Проверка кредитного лимита временно недоступна — повторите попытку позже

Для всех приведённых выше ответов ничего не заказывается и средства не начисляются к оплате. Все остальные коды аналогичны предоплатным заказам.

Примечания ​

  • Уровни доступа: аккредитованные аккаунты могут арендовать любой объём в рамках пула/максимальных лимитов с параллельными заказами; без аккредитации — 400 единиц на 5 минут, один раз (следующий заказ только после завершения предыдущей аренды). Для получения аккредитации обратитесь в службу поддержки Netts.
  • Минимум: 400 единиц. Максимум: 5000 единиц на заказ (текущая конфигурация).
  • Периоды: 5m (300 с) и 1h (3600 с, только для аккредитованных аккаунтов). Bandwidth автоматически отзывается по истечении периода.
  • Без буфера: делегируется ровно запрошенный объём.
  • hash является массивом: один заказ может порождать до 10 хешей делегирования — все они возвращаются в ответе.
  • Ценообразование: оплата в TRX в зависимости от запрошенного объёма и периода; тарифы могут меняться в зависимости от времени суток. Актуальные цены уточняйте в поддержке.
  • Компенсация за мелкие заказы (делегирование): для заказов менее 1000 единиц к цене добавляется фиксированная комиссия 0.372 TRX в качестве компенсации за ончейн-делегирование и возврат. Для заказов от 1000 единиц и выше данная надбавка отсутствует.
  • Компенсация за отправку TRX: если заказ выполняется путём отправки TRX (fulfilledBy = trx), вместо этого добавляется фиксированная комиссия 0.268 TRX (компенсация за ончейн-перевод TRX).
  • trx_send: только для amount = 400; если нет доступной bandwidth, на адрес отправляются TRX, чтобы транзакция всё равно прошла.
  • check: пропускает делегирование (и списание оплаты), если у получателя уже есть более 400 bandwidth.
  • Формат ID заказа: B5M… (5 минут) / B1H… (1 час).
  • Таймаут ответа: до ~12 секунд при ожидании делегирования; обычно 1–2 секунды.