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

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/bandwidth

Header Permintaan

HeaderDiperlukanDeskripsi
Content-TypeYaapplication/json
X-API-KEYYaKunci API Anda dari dasbor Netts
X-Real-IPYaAlamat IP dari whitelist Anda
X-Idempotency-KeyTidakKunci 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

ParameterTipeDiperlukanDeskripsi
amountintegerYaUnit Bandwidth yang akan disewa (minimum: 400, maksimum: 5000)
receiveAddressstringYaAlamat TRON yang akan menerima Bandwidth (T…, 34 karakter, base58)
periodstringYaDurasi sewa: "5m" (5 menit) atau "1h" (1 jam)
trx_sendbooleanTidakTransaksi 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
checkbooleanTidakJika true dan penerima sudah memiliki lebih dari 400 Bandwidth, pesanan tidak didelegasikan dan tidak ada dana yang ditagih (status enough). Default false
testbooleanTidakUji 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-Key agar 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

BidangTipeDeskripsi
detail.codeinteger10000 didelegasikan/TRX, 10002 cukup, 10001 sedang diproses
detail.statusstringcompleted / enough / processing / failed
detail.data.orderIdstringID Pesanan, format B5M… (5m) / B1H… (1h) — gunakan ini untuk endpoint status
detail.data.paidTRXnumberJumlah yang ditagihkan dalam TRX (0 jika enough)
detail.data.fulfilledBystringbandwidth (didelegasikan) / trx (TRX terkirim)
detail.data.hasharrayHash transaksi delegasi (hingga 10). Selalu berupa larik (kosong untuk cabang TRX)
detail.data.trxSendHasharrayHash transfer TRX, hanya ada jika fulfilledBy = trx
detail.data.bandwidthintegerUnit Bandwidth yang didelegasikan
detail.data.periodstringPeriode 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 pesananHTTPcodestatus
Selesai20010000completed (dengan hash / trxSendHash)
Sedang berlangsung20010001processing
Sudah cukup20010002enough
Gagal2005003failed
Tidak ditemukan / bukan milik Anda404-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 pesananHTTPcodestatusHasil
Didelegasikan → ditarik kembali sekarang20010004reclaimedreclaimHash (hash transaksi pembatalan delegasi)
Sudah ditarik kembali20010004reclaimedreclaimHash + pesan "already reclaimed"
Tidak dalam status didelegasikan (tidak ada yang bisa ditarik kembali)4005005failed
Penarikan kembali belum selesai5035003failedcoba lagi segera
Tidak ditemukan / bukan milik Anda404-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

KodeDeskripsiStatus HTTP
10000Berhasil (didelegasikan, atau TRX dikirim)200
10000Berhasil (respons dalam tembolok)208
10001Diterima, sedang diproses oleh penyedia eksternal202
10002Penerima sudah memiliki cukup Bandwidth (tidak dikenakan biaya)200
10003Uji coba — pratinjau hasil + harga, tidak ada biaya yang ditagihkan (test=true)200
10004Bandwidth ditarik kembali (pembatalan delegasi sukarela) — reclaimHash dikembalikan200
-Permintaan duplikat masih diproses409
-1Kunci API tidak valid / IP tidak ada dalam whitelist401
1004Saldo tidak cukup403
1005Tidak ada alamat pembayar untuk pengguna400
5004Jumlah/periode tidak valid (validasi)400
5005Tidak ada yang ditarik kembali (pesanan tidak dalam status didelegasikan)400
5007Tanpa akreditasi — hanya satu sewa pada satu waktu; pesanan sebelumnya masih aktif (tunggu hingga berakhir)503
5008Tanpa akreditasi — hanya pesanan 400 unit yang diizinkan; akreditasi diperlukan untuk jumlah yang lebih besar503
5003Delegasi Bandwidth gagal / tidak tersedia503
5000Kesalahan server internal500

Batas Laju

PeriodeBatasDeskripsi
1 detik50 permintaanMaksimum 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 base64
bash
# 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-Key yang diberikan harus berupa string base64 dengan 16–64 karakter (kumpulan karakter A–Z a–z 0–9 + / = _ -). Kunci yang salah format atau terlalu panjang akan ditolak dengan HTTP 400 (code 5004).

Kode StatusArti
200Berhasil diproses (permintaan pertama)
208Sudah berhasil diproses — respons tembolok dikembalikan (tidak ada tagihan kedua)
409Permintaan 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 dengan X-Idempotency-Key yang sama — pesanan akan dicoba kembali alih-alih mengembalikan kesalahan lama. Saat upaya masih berlangsung, Anda akan menerima 409; 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) dan 1h (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.