Appearance
POST /apiv2/bandwidth
Sewa Bandwidth TRON dan delegasikan ke alamat penerima untuk periode tetap (5 menit atau 1 jam).
⚠️ Tingkatan akses.
- Akun terakreditasi dapat menyewa jumlah berapa pun (hingga 5000) dalam batas ukuran pool dan batas maksimum, dengan beberapa pesanan bersamaan. Akreditasi diberikan oleh dukungan Netts.
- Tanpa akreditasi Anda dapat menyewa 400 unit satu kali — pesanan berikutnya hanya diizinkan setelah sewa sebelumnya berakhir. Permintaan untuk jumlah selain 400, atau pesanan kedua saat pesanan pertama masih aktif, akan ditolak.
URL Endpoint
POST https://netts.io/apiv2/bandwidthHeader Permintaan
| Header | Diperlukan | Deskripsi |
|---|---|---|
| Content-Type | Ya | application/json |
| X-API-KEY | Ya | Kunci API Anda dari dasbor Netts |
| X-Real-IP | Ya | Alamat IP dari whitelist Anda |
| X-Idempotency-Key | Tidak | Kunci opsional yang dibuat oleh klien (base64) untuk mencoba ulang dengan aman tanpa membuat pesanan ganda. Jika diabaikan, server akan membuatnya secara otomatis |
Isi Permintaan
json
{
"amount": 1500,
"receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"period": "5m"
}Parameter
| Parameter | Tipe | Diperlukan | Deskripsi |
|---|---|---|---|
| amount | integer | Ya | Unit Bandwidth yang akan disewa (minimum: 400, maksimum: 5000) |
| receiveAddress | string | Ya | Alamat TRON yang akan menerima Bandwidth (T…, 34 karakter, base58) |
| period | string | Ya | Durasi sewa: "5m" (5 menit) atau "1h" (1 jam) |
| trx_send | boolean | Tidak | Transaksi terjamin: jika tidak ada Bandwidth yang tersedia, TRX akan dikirimkan ke alamat tersebut sehingga transaksi tetap berhasil. Hanya berfungsi jika amount = 400 (jika tidak, akan diabaikan). Default false |
| check | boolean | Tidak | Jika true dan penerima sudah memiliki lebih dari 400 Bandwidth, pesanan tidak didelegasikan dan tidak ada dana yang ditagih (status enough). Default false |
| test | boolean | Tidak | Uji coba (dry run). Jika true, alur pesanan penuh akan disimulasikan — respons memberi tahu Anda hasil yang akan terjadi dan harga yang akan ditagihkan — tanpa tindakan on-chain apa pun dan tanpa membebankan biaya. Default false |
Contoh Permintaan
Contoh di bawah ini juga membuat dan mengirim
X-Idempotency-Keyagar pengulangan yang tidak disengaja tidak membuat pesanan kedua. Lihat Idempotensi untuk aturan selengkapnya.
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)}")Contoh klien lengkap (Python + cURL) disediakan bersama paket layanan (handler_bandwidth/doc/client_example/).
Respons
Berhasil — Bandwidth didelegasikan (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"
}
}
}Berhasil — TRX dikirim sebagai pengganti Bandwidth (200 OK, hanya amount=400 + trx_send=true)
Saat pool tidak memiliki Bandwidth dan trx_send diaktifkan, TRX akan dikirimkan ke alamat tersebut sehingga transaksi tetap berhasil. Biaya tetap berlaku dalam kasus ini, terlepas dari periode yang diminta.
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"
}
}
}Sudah cukup — tidak dikenakan biaya (200 OK, hanya dengan check=true)
json
{
"detail": {
"code": 10002,
"status": "enough",
"msg": "enough band for 1 transfer",
"data": { "orderId": "B5M<key14>", "paidTRX": 0, "bandwidth": 400, "period": "5m" }
}
}Sedang diproses — penyedia eksternal (202 Accepted)
Dikembalikan saat pesanan diserahkan ke penyedia eksternal secara asinkron. Lakukan polling pada endpoint status (di bawah) menggunakan orderId hingga selesai.
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" }
}
}Uji coba (200 OK, hanya dengan test=true)
Seluruh alur pesanan disimulasikan. testAction memberi tahu Anda apa yang akan terjadi dan wouldCostTRX berapa biaya yang akan dikenakan. Tidak ada yang didelegasikan, tidak ada TRX yang dikirim, tidak ada biaya yang ditagihkan (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
}
}
}Nilai testAction: would_delegate (Bandwidth akan didelegasikan), would_trx_send (tidak ada Bandwidth, amount=400 + trx_send → TRX akan dikirim), enough (penerima sudah memiliki cukup, dengan check=true), atau would_error:<reason> (misalnya no_bandwidth, not_whitelisted).
Bidang Respons
| Bidang | Tipe | Deskripsi |
|---|---|---|
| detail.code | integer | 10000 didelegasikan/TRX, 10002 cukup, 10001 sedang diproses |
| detail.status | string | completed / enough / processing / failed |
| detail.data.orderId | string | ID Pesanan, format B5M… (5m) / B1H… (1h) — gunakan ini untuk endpoint status |
| detail.data.paidTRX | number | Jumlah yang ditagihkan dalam TRX (0 jika enough) |
| detail.data.fulfilledBy | string | bandwidth (didelegasikan) / trx (TRX terkirim) |
| detail.data.hash | array | Hash transaksi delegasi (hingga 10). Selalu berupa larik (kosong untuk cabang TRX) |
| detail.data.trxSendHash | array | Hash transfer TRX, hanya ada jika fulfilledBy = trx |
| detail.data.bandwidth | integer | Unit Bandwidth yang didelegasikan |
| detail.data.period | string | Periode sewa (5m / 1h) |
Endpoint Status
GET https://netts.io/apiv2/bandwidth/status/{orderId}Header: X-API-KEY + X-Real-IP (pesanan harus milik pengguna yang diautentikasi).
| Status pesanan | HTTP | code | status |
|---|---|---|---|
| Selesai | 200 | 10000 | completed (dengan hash / trxSendHash) |
| Sedang berlangsung | 200 | 10001 | processing |
| Sudah cukup | 200 | 10002 | enough |
| Gagal | 200 | 5003 | failed |
| Tidak ditemukan / bukan milik Anda | 404 | -1 | — |
Endpoint Penarikan Kembali
Tarik kembali (batalkan delegasi) Bandwidth secara sukarela dari salah satu pesanan Anda yang telah didelegasikan sebelum periodenya berakhir. Bandwidth didelegasikan kembali (undelegate) secara otomatis dan hash transaksi akan dikembalikan.
POST https://netts.io/apiv2/bandwidth/reclaim/{orderId}Header: X-API-KEY + X-Real-IP (pesanan harus milik pengguna yang diautentikasi).
| Status pesanan | HTTP | code | status | Hasil |
|---|---|---|---|---|
| Didelegasikan → ditarik kembali sekarang | 200 | 10004 | reclaimed | reclaimHash (hash transaksi pembatalan delegasi) |
| Sudah ditarik kembali | 200 | 10004 | reclaimed | reclaimHash + pesan "already reclaimed" |
| Tidak dalam status didelegasikan (tidak ada yang bisa ditarik kembali) | 400 | 5005 | failed | — |
| Penarikan kembali belum selesai | 503 | 5003 | failed | coba lagi segera |
| Tidak ditemukan / bukan milik Anda | 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)}")Biaya sewa tidak dikembalikan pada penarikan kembali lebih awal yang bersifat sukarela — penarikan kembali hanya mengembalikan Bandwidth yang didelegasikan ke pool sebelum periodenya berakhir.
Respons Kesalahan
Kesalahan Autentikasi (401)
json
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }Saldo Tidak Cukup (403)
json
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient funds" } }Kesalahan Validasi (400)
json
{ "detail": { "code": 5004, "status": "failed", "msg": "Bandwidth amount out of range (400..5000)" } }Delegasi Gagal / Layanan Tidak Tersedia (503)
json
{ "detail": { "code": 5003, "status": "failed", "msg": "Bandwidth delegation failed" } }Referensi Kode Kesalahan
| Kode | Deskripsi | Status HTTP |
|---|---|---|
10000 | Berhasil (didelegasikan, atau TRX dikirim) | 200 |
10000 | Berhasil (respons dalam tembolok) | 208 |
10001 | Diterima, sedang diproses oleh penyedia eksternal | 202 |
10002 | Penerima sudah memiliki cukup Bandwidth (tidak dikenakan biaya) | 200 |
10003 | Uji coba — pratinjau hasil + harga, tidak ada biaya yang ditagihkan (test=true) | 200 |
10004 | Bandwidth ditarik kembali (pembatalan delegasi sukarela) — reclaimHash dikembalikan | 200 |
- | Permintaan duplikat masih diproses | 409 |
-1 | Kunci API tidak valid / IP tidak ada dalam whitelist | 401 |
1004 | Saldo tidak cukup | 403 |
1005 | Tidak ada alamat pembayar untuk pengguna | 400 |
5004 | Jumlah/periode tidak valid (validasi) | 400 |
5005 | Tidak ada yang ditarik kembali (pesanan tidak dalam status didelegasikan) | 400 |
5007 | Tanpa akreditasi — hanya satu sewa pada satu waktu; pesanan sebelumnya masih aktif (tunggu hingga berakhir) | 503 |
5008 | Tanpa akreditasi — hanya pesanan 400 unit yang diizinkan; akreditasi diperlukan untuk jumlah yang lebih besar | 503 |
5003 | Delegasi Bandwidth gagal / tidak tersedia | 503 |
5000 | Kesalahan server internal | 500 |
Batas Laju
| Periode | Batas | Deskripsi |
|---|---|---|
| 1 detik | 50 permintaan | Maksimum 50 permintaan per detik per IP |
Batas Laju Terlampaui (429)
json
{ "message": "API rate limit exceeded" }Idempotensi
Kirim header opsional X-Idempotency-Key agar pengulangan yang tidak disengaja tidak membuat pesanan kedua — respons asli akan dikembalikan dengan HTTP 208. Jika Anda tidak mengirim header tersebut, server akan membuat kunci secara otomatis dari parameter permintaan Anda dalam jendela waktu singkat.
Cara membuat kunci
Kunci berupa base64( HMAC-SHA256( secret, message ) ) — string base64 sepanjang 44 karakter, di mana:
- secret = kunci API Anda (
X-API-KEY); - message = bidang yang digabungkan dengan
:—receiveAddress:amount:period:nonce.
nonce adalah nilai apa pun yang stabil di seluruh percobaan ulang pesanan logis yang sama tetapi berbeda antara pesanan yang berbeda — mis. UUID yang Anda simpan untuk pesanan tersebut, atau bucket stempel waktu kasar. Buat kunci satu kali per pesanan dan kirim ulang nilai yang persis sama pada setiap percobaan ulang.
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 base64bash
# then send it as a header:
-H "X-Idempotency-Key: <base64_key>"Menyertakan period dalam pesan sangat penting: menyewa untuk alamat yang sama selama 5m dan 1h adalah pesanan yang berbeda dan harus menghasilkan kunci yang berbeda.
Validasi.
X-Idempotency-Keyyang diberikan harus berupa string base64 dengan 16–64 karakter (kumpulan karakterA–Z a–z 0–9 + / = _ -). Kunci yang salah format atau terlalu panjang akan ditolak dengan HTTP 400 (code 5004).
| Kode Status | Arti |
|---|---|
| 200 | Berhasil diproses (permintaan pertama) |
| 208 | Sudah berhasil diproses — respons tembolok dikembalikan (tidak ada tagihan kedua) |
| 409 | Permintaan yang sama saat ini sedang diproses — tunggu, jangan coba lagi sekarang |
Mencoba lagi setelah kegagalan. Hanya hasil yang berhasil (
completed/enough) yang disimpan dalam tembolok. Jika percobaan sebelumnya gagal atau kehabisan waktu (tidak ada dana yang ditagihkan), Anda dapat dengan aman mencoba lagi denganX-Idempotency-Keyyang sama — pesanan akan dicoba kembali alih-alih mengembalikan kesalahan lama. Saat upaya masih berlangsung, Anda akan menerima409; tunggu dan coba lagi.
Catatan
- Tingkatan akses: akun terakreditasi dapat menyewa dalam jumlah berapa pun dalam batas pool/maksimum dengan pesanan bersamaan; tanpa akreditasi — 400 unit satu kali (pesanan berikutnya hanya setelah sewa sebelumnya berakhir). Hubungi dukungan Netts untuk akreditasi.
- Minimum: 400 unit. Maksimum: 5000 unit per pesanan (konfigurasi saat ini).
- Periode:
5m(300 d) dan1h(3600 d). Bandwidth akan ditarik kembali secara otomatis saat periode berakhir. - Tanpa buffer: tepat jumlah yang diminta yang didelegasikan.
- hash berupa larik: satu pesanan dapat menghasilkan hingga 10 hash delegasi — semuanya dikembalikan.
- Penetapan harga: ditagihkan dalam TRX, berdasarkan jumlah dan periode yang diminta; tarif dapat bervariasi menurut waktu. Hubungi dukungan untuk harga saat ini.
- Kompensasi pesanan kecil (delegasi): untuk pesanan di bawah 1000 unit, biaya tetap sebesar 0.372 TRX ditambahkan ke harga sebagai kompensasi untuk delegasi dan penarikan kembali on-chain. Pesanan 1000 unit atau lebih tidak memiliki penambahan tersebut.
- Kompensasi pengiriman TRX: jika pesanan dipenuhi dengan mengirim TRX (
fulfilledBy = trx), biaya tetap sebesar 0.268 TRX ditambahkan sebagai gantinya (kompensasi untuk transfer TRX on-chain). - trx_send: hanya untuk
amount = 400; jika tidak ada Bandwidth yang tersedia, TRX akan dikirimkan ke alamat tersebut sehingga transaksi tetap berhasil. - check: melewati delegasi (dan penagihan biaya) saat penerima sudah memiliki lebih dari 400 Bandwidth.
- Format ID Pesanan:
B5M…(5 menit) /B1H…(1 jam). - Batas waktu respons: hingga ~12 detik saat menunggu delegasi; biasanya 1–2 detik.