Appearance
POST /apiv2/bandwidth
Sewa Bandwidth TRON dan delegasikan ke alamat penerima untuk jangka waktu tertentu: 5 menit, atau 1 jam untuk akun terakreditasi.
⚠️ Tingkatan akses.
- Akun terakreditasi menyewa jumlah berapa pun (hingga 5000) selama 5 menit atau 1 jam dalam ukuran pool dan batas maksimum, dengan beberapa pesanan bersamaan. Akreditasi diberikan oleh dukungan Netts.
- Tanpa akreditasi Anda dapat menyewa 400 unit selama 5 menit, sekali — pesanan berikutnya hanya diizinkan setelah sewa sebelumnya berakhir. Permintaan untuk jumlah selain 400, untuk 1 jam, 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 Permintaan
| 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, hanya akun terakreditasi) |
| trx_send | boolean | Tidak | Transaksi bergaransi: jika tidak ada Bandwidth yang tersedia, kirim TRX ke alamat tersebut agar transaksi tetap berhasil. Hanya berfungsi jika amount = 400 (diabaikan jika tidak). Default false |
| check | boolean | Tidak | Jika true dan penerima sudah memiliki lebih dari 400 Bandwidth, pesanan tidak didelegasikan dan tidak ada dana yang ditagihkan (status enough). Default false |
| test | boolean | Tidak | Uji coba. 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 pembebanan biaya. Default false |
Contoh
Contoh di bawah ini juga membuat dan mengirim
X-Idempotency-Keysehingga pengulangan yang tidak disengaja tidak akan membuat pesanan kedua. Lihat Idempotensi untuk aturan lengkapnya.
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 dalam 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 ganti Bandwidth (200 OK, hanya amount=400 + trx_send=true)
Ketika pool tidak memiliki Bandwidth dan trx_send diaktifkan, TRX dikirim ke alamat tersebut agar transaksi tetap berjalan. 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 diteruskan ke penyedia eksternal secara asinkron. Lakukan polling pada status endpoint (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 memberi tahu apa yang akan ditagihkan. Tidak ada yang didelegasikan, tidak ada TRX yang dikirim, tidak ada 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 memproses |
| detail.status | string | completed / enough / processing / failed |
| detail.data.orderId | string | ID Pesanan, format B5M… (5m) / B1H… (1h) — gunakan ini untuk status endpoint |
| detail.data.paidTRX | number | Jumlah yang ditagihkan dalam TRX (0 saat enough) |
| detail.data.fulfilledBy | string | bandwidth (didelegasikan) / trx (TRX terkirim) |
| detail.data.hash | array | Hash transaksi delegasi (hingga 10). Selalu berupa array (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 Klaim Kembali
Klaim kembali (batalkan delegasi) secara sukarela atas Bandwidth dari salah satu pesanan Anda yang telah didelegasikan sebelum periodenya berakhir. Bandwidth dibatalkan delegasinya secara otomatis dan hash transaksi 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 → diklaim kembali sekarang | 200 | 10004 | reclaimed | reclaimHash (hash transaksi pembatalan delegasi) |
| Sudah diklaim kembali | 200 | 10004 | reclaimed | reclaimHash + pesan "already reclaimed" |
| Tidak dalam status didelegasikan (tidak ada yang perlu diklaim) | 400 | 5005 | failed | — |
| Klaim kembali belum selesai | 503 | 5003 | failed | coba lagi sesaat lagi |
| 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 klaim kembali dini sukarela — mengklaim 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 terkirim) | 200 |
10000 | Berhasil (respons dalam cache) | 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 yang ditagihkan (test=true) | 200 |
10004 | Bandwidth diklaim kembali (pembatalan delegasi sukarela) — reclaimHash dikembalikan | 200 |
- | Permintaan duplikat masih diproses | 409 |
-1 | Kunci API tidak valid / IP tidak ada di whitelist | 401 |
1004 | Saldo tidak mencukupi | 403 |
1005 | Tidak ada alamat pembayar untuk pengguna | 400 |
5004 | Jumlah/periode tidak valid (validasi) | 400 |
5005 | Tidak ada yang perlu diklaim kembali (pesanan tidak dalam status didelegasikan) | 400 |
5007 | Tanpa akreditasi — hanya satu sewa dalam satu waktu; pesanan sebelumnya masih aktif (tunggu hingga berakhir) | 503 |
5008 | Tanpa akreditasi — hanya pesanan 400 unit selama 5 menit yang diizinkan; akreditasi diperlukan untuk jumlah yang lebih besar atau 1 jam | 503 |
5003 | Delegasi Bandwidth gagal / tidak tersedia | 503 |
5000 | Kesalahan server internal | 500 |
Batas Frekuensi
| 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 rentang waktu singkat.
Cara membuat kunci
Kunci adalah base64( HMAC-SHA256( secret, message ) ) — string base64 sepanjang 44 karakter, di mana:
- secret = kunci API Anda (
X-API-KEY); - message = bidang-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 rentang stempel waktu kasar. Hasilkan kunci sekali per pesanan dan kirim ulang nilai yang sama persis 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 5 menit dan 1 jam adalah pesanan yang berbeda dan harus menghasilkan kunci yang berbeda.
Validasi.
X-Idempotency-Keyyang diberikan harus berupa string base64 sepanjang 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 dalam cache dikembalikan (tidak ada tagihan kedua) |
| 409 | Permintaan yang sama saat ini sedang diproses — tunggu, jangan coba lagi sekarang |
Mencoba kembali setelah kegagalan. Hanya hasil yang berhasil (
completed/enough) yang disimpan dalam cache. Jika upaya sebelumnya gagal atau mengalami batas waktu (tidak ada dana yang ditagihkan), Anda dapat dengan aman mencoba lagi denganX-Idempotency-Keyyang sama — pesanan akan dicoba kembali daripada mengembalikan pesan kesalahan lama. Saat upaya masih berlangsung Anda akan menerima409; tunggu dan coba lagi.
Akun Pascabayar
Akun dengan penagihan pascabayar menggunakan endpoint, URL, header, dan body permintaan yang sama dengan yang lainnya. Perbedaannya terletak pada cara pembayaran pesanan:
- Tidak ada yang dipotong dari deposit Anda. Setiap pesanan yang dikirimkan ditambahkan ke saldo tagihan akun Anda dalam mata uang penyelesaian yang disepakati dalam kontrak Anda. Anda membayarnya melalui faktur, sesuai dengan perjanjian Anda.
- Akun Anda memiliki batas kredit. Selama jumlah yang jatuh tempo masih dalam batas, pesanan tetap diterima bahkan dengan deposit nol. Sewa untuk 5 menit dan 1 jam diperhitungkan dalam batas Bandwidth yang sama.
- Hanya layanan yang berhasil dikirimkan yang ditagihkan: Bandwidth yang didelegasikan ke alamat, atau TRX yang dikirim sebagai gantinya (
fulfilledBy = trx). Jumlahnya sama dengan pesanan prabayar. - Pesanan yang ditolak, tidak dieksekusi, uji coba (
test: true) atau dijawab denganenough(check: true) tidak memakan biaya. - Klaim kembali sukarela lebih awal tidak mengurangi jumlah jatuh tempo, sama seperti pesanan prabayar.
- Tingkatan akses, jumlah, periode, dan semua aturan lain dari endpoint ini sama dengan akun prabayar.
Penagihan pascabayar diaktifkan oleh Netts untuk suatu akun berdasarkan permintaan. Setiap respons memberi tahu Anda bagaimana pesanan dibayar: paymentMode adalah postpaid atau prepaid.
Pengecekan harga (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 adalah jumlah yang akan ditambahkan ke saldo jatuh tempo Anda, dalam TRX. Tidak ada yang didelegasikan atau ditagihkan.
Pesanan berhasil
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"
}
}
}| Bidang | Deskripsi |
|---|---|
| paidTRX | Biaya layanan dalam TRX. Untuk akun pascabayar biaya ini tidak dipotong dari deposit |
| paymentMode | postpaid |
| totalTRX | Jumlah persis, 6 angka desimal |
Semua bidang lainnya, termasuk cabang TRX (fulfilledBy = trx, trxSendHash), sama dengan pesanan prabayar.
Batas kredit tercapai (402)
json
{
"detail": {
"code": 1004,
"msg": "Postpaid credit limit reached.",
"paymentMode": "postpaid",
"reason": "limit_reached"
}
}Pesanan tidak dieksekusi dan tidak ada yang ditagihkan. Pesanan baru akan diterima kembali setelah pembayaran Anda terdaftar atau batas kredit Anda dinaikkan.
Kode kesalahan pascabayar
| Kode | HTTP | Deskripsi |
|---|---|---|
1004 | 402 | Batas kredit pascabayar tercapai |
5032 | 503 | Harga untuk sementara tidak tersedia |
5034 | 503 | Penagihan untuk sementara tidak tersedia — pesanan tidak diterima |
5036 | 503 | Pemeriksaan kredit untuk sementara tidak tersedia — coba lagi nanti |
Untuk semua respons di atas, tidak ada yang dipesan dan tidak ada yang ditagihkan. Semua kode lainnya sama dengan pesanan prabayar.
Catatan
- Tingkatan akses: akun terakreditasi menyewa dalam jumlah berapa pun dalam batas pool/maksimum dengan pesanan bersamaan; tanpa akreditasi — 400 unit selama 5 menit, sekali (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 dtk) dan1h(3600 dtk, hanya akun terakreditasi). Bandwidth secara otomatis diklaim kembali ketika periodenya berakhir. - Tanpa buffer: persis jumlah yang diminta yang didelegasikan.
- hash adalah array: satu pesanan dapat menghasilkan hingga 10 hash delegasi — semuanya dikembalikan.
- 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 on-chain dan klaim kembali. Pesanan 1000 unit atau lebih tidak dikenakan biaya tambahan tersebut.
- Kompensasi kirim-TRX: saat pesanan dipenuhi dengan mengirimkan 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 dikirim ke alamat sehingga transaksi tetap berhasil. - check: melewati delegasi (dan pembebanan biaya) jika 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.