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

POST /apiv2/bandwidth

Аренда TRON Bandwidth и делегирование его на адрес получателя на фиксированный период (5 минут или 1 час).

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

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

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 ))   # стабилен для повторных попыток в окне 2 с; или ваш собственный 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" ) )
# Сгенерируйте ОДИН РАЗ на заказ и отправляйте то же самое значение при каждом повторе.
nonce = str(int(time.time() // 2))   # корзина 2 с; или ваш собственный 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"ID заказа: {d['orderId']}")
    print(f"Хеши:      {d['hash']}")          # массив хешей транзакций делегирования
    print(f"Bandwidth: {d['bandwidth']} на {d['period']}")
    print(f"Стоимость: {d['paidTRX']} TRX")
else:
    print(f"Код: {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"
        }
    }
}

Успех — отправлен TRX вместо Bandwidth (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)

Возвращается, когда заказ асинхронно передается внешнему провайдеру. Опрашивайте эндпоинт статуса (ниже), используя 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… (5m) / B1H… (1h) — используйте его для эндпоинта статуса
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
Завершен20010000completedhash / trxSendHash)
В процессе20010001processing
Уже достаточно20010002enough
Ошибка2005003failed
Не найден / чужой404-1

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

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

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

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

Состояние заказаHTTPcodestatusРезультат
Делегирован → отозван сейчас20010004reclaimedreclaimHash (хеши транзакций undelegate)
Уже отозван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..."   # orderId из вашего ответа на запрос аренды
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"Отозвано: {detail['data']['reclaimHash']} ({detail['msg']})")
else:
    print(f"Код {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 отозван (добровольный undelegate) — возвращен reclaimHash200
-Дублирующий запрос все еще обрабатывается409
-1Неверный API-ключ / IP не в белом списке401
1004Недостаточный баланс403
1005Нет адреса плательщика для пользователя400
5004Недопустимое количество/период (валидация)400
5005Нечего отзывать (заказ не в состоянии делегирования)400
5007Без аккредитации — только одна аренда одновременно; предыдущий заказ все еще активен (дождитесь окончания)503
5008Без аккредитации — разрешены заказы только на 400 единиц; для больших объемов требуется аккредитация503
5003Ошибка делегирования Bandwidth / сервис недоступен503
5000Внутренняя ошибка сервера500

Лимиты запросов (Rate Limits)

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

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

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

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

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

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

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

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

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

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 секунды; или ваш собственный UUID заказа
    message = f"{receive_address}:{amount}:{period}:{nonce}"
    digest = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).digest()
    return base64.b64encode(digest).decode()  # base64 из 44 символов
bash
# затем передайте его в качестве заголовка:
-H "X-Idempotency-Key: <base64_key>"

Включение period в сообщение крайне важно: аренда на один и тот же адрес на 5m и на 1h — это разные заказы, и они должны давать разные ключи.

Валидация. Передаваемый 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; подождите и повторите.

Примечания

  • Уровни доступа: аккредитованные аккаунты арендуют любой объем в пределах лимитов пула/максимума с параллельными заказами; без аккредитации — 400 единиц один раз (следующий заказ только после завершения предыдущей аренды). Свяжитесь с поддержкой 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 секунды.