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) для безпечних повторних спроб без дублювання замовлень. Якщо опущено, сервер генерує його автоматично |
Тіло запиту
{
"amount": 1500,
"receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"period": "5m"
}Параметри
| Параметр | Тип | Обов'язковий | Опис |
|---|---|---|---|
| amount | integer | Так | Кількість одиниць Bandwidth для оренди (мінімум: 400, максимум: 5000) |
| receiveAddress | string | Так | TRON-адреса, яка отримає Bandwidth (T…, 34 символи, base58) |
| period | string | Так | Тривалість оренди: "5m" (5 хвилин) або "1h" (1 година, лише для акредитованих акаунтів) |
| trx_send | boolean | Ні | Гарантована транзакція: якщо Bandwidth недоступна, на адресу надсилається TRX, щоб транзакція все одно відбулася. Працює лише тоді, коли amount = 400 (в інших випадках ігнорується). За замовчуванням false |
| check | boolean | Ні | Якщо true і отримувач вже має понад 400 Bandwidth, замовлення не делегується і кошти не списуються (статус enough). За замовчуванням false |
| test | boolean | Ні | Тестовий запуск. Якщо true, симулюється повний процес замовлення — відповідь повідомляє про результат, який би відбувся, та ціну, яка була б списана, — без жодних дій у блокчейні та без списання коштів. За замовчуванням false |
Приклади запитів
Наведені нижче приклади також формують і надсилають
X-Idempotency-Key, щоб випадковий повторний запит не створив друге замовлення. Дивіться повні правила у розділі Ідемпотентність.
cURL
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
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)
{
"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, щоб транзакція все одно пройшла. У цьому випадку застосовується фіксована плата незалежно від запитаного періоду.
{
"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)
{
"detail": {
"code": 10002,
"status": "enough",
"msg": "enough band for 1 transfer",
"data": { "orderId": "B5M<key14>", "paidTRX": 0, "bandwidth": 400, "period": "5m" }
}
}Обробка — зовнішній провайдер (202 Accepted)
Повертається, коли замовлення передається зовнішньому провайдеру асинхронно. Опитуйте ендпоінт статусу (нижче), використовуючи orderId, доки виконання не завершиться.
{
"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).
{
"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.code | integer | 10000 делеговано/TRX, 10002 достатньо, 10001 в обробці |
| detail.status | string | completed / enough / processing / failed |
| detail.data.orderId | string | ID замовлення, формат B5M… (5m) / B1H… (1h) — використовуйте його для ендпоінта статусу |
| detail.data.paidTRX | number | Списана сума в TRX (0 у разі enough) |
| detail.data.fulfilledBy | string | bandwidth (делеговано) / trx (надіслано TRX) |
| detail.data.hash | array | Хеші транзакцій делегування (до 10). Завжди масив (порожній для гілки TRX) |
| detail.data.trxSendHash | array | Хеш(і) транзакції переказу TRX, присутні лише за умови fulfilledBy = trx |
| detail.data.bandwidth | integer | Делеговані одиниці Bandwidth |
| detail.data.period | string | Період оренди (5m / 1h) |
Кінцева точка статусу
GET https://netts.io/apiv2/bandwidth/status/{orderId}Заголовки: X-API-KEY + X-Real-IP (замовлення має належати автентифікованому користувачу).
| Стан замовлення | HTTP | code | status |
|---|---|---|---|
| Завершено | 200 | 10000 | completed (із hash / trxSendHash) |
| У процесі | 200 | 10001 | processing |
| Вже достатньо | 200 | 10002 | enough |
| Помилка | 200 | 5003 | failed |
| Не знайдено / не ваше | 404 | -1 | — |
Ендпоінт повернення
Добровільне відкликання (undelegate) Bandwidth для одного з ваших делегованих замовлень до закінчення його періоду. Bandwidth автоматично відкликається, і повертається хеш транзакції.
POST https://netts.io/apiv2/bandwidth/reclaim/{orderId}Заголовки: X-API-KEY + X-Real-IP (замовлення має належати автентифікованому користувачу).
| Стан замовлення | HTTP | code | status | Результат |
|---|---|---|---|---|
| Делеговано → повернено зараз | 200 | 10004 | reclaimed | reclaimHash (хеші транзакцій undelegate) |
| Вже повернено | 200 | 10004 | reclaimed | reclaimHash + повідомлення "already reclaimed" |
| Не в стані делегування (нічого повертати) | 400 | 5005 | failed | — |
| Повернення ще не завершено | 503 | 5003 | failed | повторіть спробу незабаром |
| Не знайдено / не ваше | 404 | -1 | — | — |
curl -X POST https://netts.io/apiv2/bandwidth/reclaim/B5M<...> \
-H "X-API-KEY: your_api_key" -H "X-Real-IP: your_whitelisted_ip"{
"detail": {
"code": 10004,
"status": "reclaimed",
"msg": "Bandwidth reclaimed",
"data": { "orderId": "B5M<...>", "reclaimHash": ["<txid>"] }
}
}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)
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }Недостатній баланс (403)
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient funds" } }Помилка валідації (400)
{ "detail": { "code": 5004, "status": "failed", "msg": "Bandwidth amount out of range (400..5000)" } }Збій делегування / Сервіс недоступний (503)
{ "detail": { "code": 5003, "status": "failed", "msg": "Bandwidth delegation failed" } }Довідник кодів помилок
| Код | Опис | HTTP-статус |
|---|---|---|
10000 | Успішно (делеговано або надіслано TRX) | 200 |
10000 | Успішно (кешована відповідь) | 208 |
10001 | Прийнято, обробляється зовнішнім провайдером | 202 |
10002 | Отримувач вже має достатньо Bandwidth (кошти не списано) | 200 |
10003 | Тестовий запуск — попередній перегляд результату та ціни, кошти не списуються (test=true) | 200 |
10004 | Bandwidth повернено (добровільний undelegate) — повертається reclaimHash | 200 |
- | Повторний запит ще обробляється | 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)
{ "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, який ви зберігаєте для цього замовлення, або приблизна часова мітка. Генеруйте ключ один раз для кожного замовлення та надсилайте те саме значення під час кожної повторної спроби.
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# then send it as a header:
-H "X-Idempotency-Key: <base64_key>"Включення period у message є важливим: оренда для однієї й тієї ж адреси на 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; зачекайте і повторіть знову.
Постоплатні акаунти
Акаунти з постоплатним розрахунком використовують той самий ендпоінт, URL, заголовки та тіло запиту, що й усі інші. Різниця полягає у способі оплати замовлення:
- З вашого депозиту нічого не списується. Кожне виконане замовлення додається до суми заборгованості вашого акаунта у валюті розрахунку, зазначеній у вашому договорі. Оплата здійснюється за інвойсом відповідно до ваших домовленостей.
- Ваш акаунт має кредитний ліміт. Поки сума заборгованості залишається в межах ліміту, замовлення приймаються навіть за нульового депозиту. Оренда на 5 хвилин і на 1 годину враховується в рамках одного ліміту Bandwidth.
- Оплачуються лише фактично надані послуги: делегована на адресу Bandwidth або надісланий замість неї TRX (
fulfilledBy = trx). Вартість така сама, як і для передоплатних замовлень. - Замовлення, яке було відхилено, не виконано, є тестовим запуском (
test: true) або отримало відповідьenough(check: true), нічого не коштує. - Добровільне раннє повернення ресурсів не зменшує суму до сплати, так само як і для передоплатних замовлень.
- Рівні доступу, обсяги, періоди та всі інші правила цього ендпоінта є ідентичними правилам для передоплатних акаунтів.
Постоплатний розрахунок підключається командою Netts для кожного акаунта за запитом. Кожна відповідь містить інформацію про спосіб оплати замовлення: paymentMode має значення postpaid або prepaid.
Перевірка вартості (test: true)
{
"amount": 1000,
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"period": "5m",
"test": true
}{
"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, яка буде додана до вашої заборгованості. Делегування та нарахування коштів не виконуються.
Успішне замовлення
{
"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. Для постоплатних акаунтів вона не списується з депозиту |
| paymentMode | postpaid |
| totalTRX | Точна сума, 6 знаків після коми |
Усі інші поля, включаючи гілку TRX (fulfilledBy = trx, trxSendHash), такі самі, як і для передплачених замовлень.
Вичерпано кредитний ліміт (402)
{
"detail": {
"code": 1004,
"msg": "Postpaid credit limit reached.",
"paymentMode": "postpaid",
"reason": "limit_reached"
}
}Замовлення не виконується, і нарахування коштів не відбувається. Прийом нових замовлень відновиться після зарахування вашого платежу або збільшення ліміту.
Коди помилок для постоплати
| Код | HTTP | Опис |
|---|---|---|
1004 | 402 | Вичерпано кредитний ліміт постоплати |
5032 | 503 | Вартість тимчасово недоступна |
5034 | 503 | Білінг тимчасово недоступний — замовлення не прийнято |
5036 | 503 | Перевірка кредитного ліміту тимчасово недоступна — повторіть спробу пізніше |
Для всіх наведених вище відповідей замовлення не створюється і кошти не нараховуються. Усі інші коди ідентичні кодам для передоплатних замовлень.
Примітки
- Рівні доступу: акредитовані акаунти орендують будь-який обсяг у межах лімітів пулу/максимальних обмежень з одночасними замовленнями; без акредитації — 400 одиниць на 5 хвилин, одноразово (наступне замовлення лише після закінчення попередньої оренди). Для отримання акредитації зверніться до служби підтримки Netts.
- Мінімум: 400 одиниць. Максимум: 5000 одиниць на замовлення (поточна конфігурація).
- Періоди:
5m(300 с) та1h(3600 с, лише для акредитованих акаунтів). Bandwidth автоматично відкликається після закінчення періоду. - Без буфера: делегується точно запитаний обсяг.
- hash є масивом: одне замовлення може створити до 10 хешів делегування — повертаються всі.
- Ціноутворення: списується в TRX на основі запитаного обсягу та періоду; тарифи можуть змінюватися залежно від часу доби. Зверніться до служби підтримки щодо актуальних тарифів.
- Компенсація за малі замовлення (делегування): для замовлень менше 1000 одиниць до вартості додається фіксована сума 0.372 TRX як компенсація за ончейн-делегування та undelegate. Для замовлень від 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 секунди.