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

POST /apiv2/order1h ​

Buat pesanan sewa Energy 1 jam melalui beberapa penyedia Energy dengan failover otomatis.

URL Endpoint ​

POST https://netts.io/apiv2/order1h

Header Permintaan ​

HeaderDiperlukanDeskripsi
Content-TypeYaapplication/json
X-API-KEYYaKunci API Anda dari dasbor Netts
X-Real-IPYaAlamat IP dari whitelist Anda

Isi Permintaan ​

json
{
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}

Parameter Permintaan ​

ParameterTipeDiperlukanDeskripsi
amountintegerYaJumlah Energy yang akan disewa (minimum: 61000, maksimum: 3000000)
receiveAddressstringYaAlamat TRON yang akan menerima Energy (format TRC-20)

Pemilihan Penyedia ​

API secara otomatis memilih penyedia Energy yang optimal berdasarkan:

  • Efisiensi biaya - Selalu menemukan harga terendah yang tersedia
  • Ketersediaan - Memastikan cadangan Energy yang cukup
  • Keandalan - Menggunakan penyedia dengan tingkat keberhasilan tinggi
  • Kecepatan - Memprioritaskan waktu pengiriman tercepat

Contoh ​

cURL ​

bash
curl -X POST https://netts.io/apiv2/order1h \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_api_key" \
  -H "X-Real-IP: your_whitelisted_ip" \
  -d '{
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
  }'

Python ​

python
import requests

url = "https://netts.io/apiv2/order1h"
headers = {
    "Content-Type": "application/json",
    "X-API-KEY": "your_api_key",
    "X-Real-IP": "your_whitelisted_ip"
}

payload = {
    "amount": 131000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}

response = requests.post(url, headers=headers, json=payload)
data = response.json()

if response.status_code == 200:
    detail = data.get('detail', {})
    order_data = detail.get('data', {})
    print(f"Order ID: {order_data.get('orderId')}")
    print(f"Transaction Hash: {order_data.get('hash')}")
    print(f"Energy Delivered: {order_data.get('energy')}")
    print(f"Cost: {order_data.get('paidTRX')} TRX")
    print(f"Delegate Address: {order_data.get('delegateAddress')}")
else:
    error_detail = data.get('detail', data)
    print(f"Error Code: {error_detail.get('code', 'N/A')}")
    print(f"Error Message: {error_detail.get('msg', error_detail)}")

Respons ​

Respons Sukses (200 OK) ​

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 2.23 TRX deducted",
        "data": {
            "orderId": "1H123456",
            "paidTRX": 2.23,
            "hash": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
            "delegateAddress": "TNp5gsJhBmZFXgCdgjMgr8pEZ8fHgXUHDq",
            "energy": 131050
        }
    }
}

Bidang Respons ​

BidangTipeDeskripsi
detail.codeintegerSelalu 10000 untuk pesanan yang berhasil
detail.msgstringPesan sukses dengan jumlah yang dipotong
detail.data.orderIdstringID pesanan terpadu (format: 1H{request_id})
detail.data.paidTRXnumberTotal biaya dalam TRX (termasuk biaya aktivasi jika alamat belum diaktifkan)
detail.data.hashstring | nullHash transaksi. Bidang selalu ada tetapi mungkin kosong - beberapa penyedia tidak mengembalikan hash secara langsung. Gunakan /apiv2/order_check setelah 1 menit untuk mendapatkan hash
detail.data.delegateAddressstringAlamat pool yang mendelegasikan Energy
detail.data.energyintegerJumlah Energy + buffer (biasanya +50)

Respons Kesalahan ​

Kesalahan Autentikasi (401) ​

json
{
    "detail": "Invalid API key or IP not in whitelist"
}

Saldo Tidak Cukup (403) ​

json
{
    "code": 1004,
    "msg": "Insufficient funds. Required: 2.23 TRX, Available: 1.50 TRX"
}

Layanan Tidak Tersedia (503) ​

json
{
    "code": 5003,
    "msg": "Service temporarily unavailable. All energy providers are currently unavailable."
}

Kesalahan Penyedia (503) ​

json
{
    "code": 5001,
    "msg": "Energy provider temporarily unavailable"
}
json
{
    "code": 5002,
    "msg": "Energy provider temporarily unavailable"
}
json
{
    "code": 5004,
    "msg": "Energy provider requires higher minimum amount"
}

Kesalahan Server Internal (500) ​

json
{
    "code": 5000,
    "msg": "Internal server error occurred"
}

Referensi Kode Kesalahan ​

KodeDeskripsiStatus HTTP
10000Berhasil200
10000Berhasil (respons ter-cache)208
-Permintaan duplikat masih diproses409
1004Saldo tidak mencukupi403
5000Kesalahan server internal500
5001Penyedia Energy tidak tersedia503
5002Penyedia Energy tidak tersedia503
5003Layanan Energy tidak tersedia503
5004Minimum penyedia Energy tidak terpenuhi503

Batas Kecepatan ​

Batas laju berikut berlaku untuk endpoint ini (per alamat IP):

PeriodeBatasDeskripsi
1 detik50 permintaanMaksimum 50 permintaan per detik

Header Batas Laju ​

http
RateLimit-Limit: 50
RateLimit-Remaining: 49
RateLimit-Reset: 1
X-RateLimit-Limit-Second: 50
X-RateLimit-Remaining-Second: 49

Batas Laju Terlampaui (429) ​

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

Idempotensi ​

API mendukung idempotensi untuk mencegah pemrosesan pesanan ganda. Saat Anda mengirim beberapa permintaan yang identik, sistem memastikan pesanan hanya diproses satu kali.

Cara Kerja Idempotensi ​

Keunikan permintaan ditentukan oleh kombinasi dari:

  • Timestamp permintaan (jendela 1 detik)
  • Jumlah Energy
  • Alamat penerima
  • Kunci API

Setiap permintaan diberikan jendela keunikan 1 detik. Untuk melindungi sistem dari penyalahgunaan dan memastikan pemrosesan yang tepat, permintaan dengan parameter identik tidak dapat dikirim lebih sering daripada sekali per detik.

Perilaku saat ini: Sistem secara otomatis melindungi klien dari percobaan ulang yang keliru pada Energy yang sudah dipesan. Jika Anda tidak sengaja mengirim permintaan yang sama dua kali, Anda tidak akan dikenakan biaya dua kali.

Menyediakan Kunci Anda Sendiri ​

Anda dapat mengatur idempotensi sendiri dengan mengirimkan header X-Idempotency-Key. Jika ada, nilai itu sendiri yang menentukan apakah suatu permintaan merupakan pengulangan, dan kombinasi otomatis di atas tidak digunakan. Jika tidak ada, tidak ada yang berubah — server menghasilkan kunci untuk Anda.

HeaderX-Idempotency-Key
FormatTepat 64 karakter heksadesimal huruf kecil — digest SHA-256
Masa berlaku24 jam dari permintaan pertama yang membawa kunci tersebut
CakupanAkun Anda. Nilai yang sama yang dikirim oleh akun lain tidak akan pernah mengembalikan hasil Anda

Kunci dengan bentuk lain apa pun — UUID dengan tanda hubung, base64, heksadesimal huruf besar — akan ditolak dengan 400 sebelum pesanan dibuat dan sebelum biaya apa pun dipotong:

json
{
    "detail": "Invalid idempotency key format. Must be 64-character hexadecimal string."
}

Formatnya berbeda dari endpoint lain. /apiv2/withdraw, /apiv2/bandwidth dan orchestrator menerima kunci base64 16–64 karakter. Endpoint ini hanya menerima digest hex 64 karakter, jadi kode pembuatan kunci yang disalin dari endpoint tersebut akan mengembalikan 400 di sini.

Cara membentuk kunci ​

Turunkan dari kunci API Anda. Itu membuat nilainya unik untuk akun Anda, dapat direproduksi pada percobaan ulang, dan tidak mungkin diperoleh oleh orang lain:

python
import hashlib
import hmac

def make_idempotency_key(api_key: str, address: str, amount: int, nonce: str) -> str:
    message = f"{address}:{amount}:{nonce}"
    return hmac.new(api_key.encode(), message.encode(), hashlib.sha256).hexdigest()

nonce milik pesanan, bukan permintaan. Tentukan sekali, saat pesanan dibuat di sisi Anda, dan berikan nilai yang sama persis pada setiap pengiriman pesanan tersebut — upaya pertama dan setiap percobaan ulang sama saja. Menghasilkan nilai baru di dalam fungsi pengiriman (str(uuid.uuid4()) pada setiap panggilan) memberi setiap upaya kunci yang berbeda, sehingga percobaan ulang setelah waktu habis diterima sebagai pesanan kedua dan dikenakan biaya lagi. Pilihan benar yang paling sederhana adalah ID pesanan yang sudah Anda miliki: ID tersebut ada sebelum upaya pertama dan tetap bertahan saat proses Anda dimulai ulang.

python
# sekali, saat pesanan muncul di sistem Anda
order = create_order(address="TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", amount=131000)

# pada upaya pertama dan pada setiap percobaan ulang — tiga input yang sama, kunci yang sama
key = make_idempotency_key(API_KEY, order.address, order.amount, order.id)

headers = {
    "Content-Type": "application/json",
    "X-API-KEY": API_KEY,
    "X-Idempotency-Key": key,
}

Kunci berlaku selama 24 jam. Setelah itu nonce yang sama bebas kembali dan memulai pesanan baru.

Jangan gunakan nilai yang dapat diperoleh orang lain — 64 angka nol, digest dari kata tetap. Kunci berbagi satu ruang di seluruh akun. Tabrakan seperti itu tidak pernah mengekspos pesanan akun lain, tetapi permintaan Anda akan ditolak dengan 409 sampai kunci mereka kedaluwarsa, yang bukan merupakan jawaban yang Anda inginkan di tengah percobaan ulang.

Membuat Dua Pesanan Identik ​

Terkadang Anda benar-benar menginginkan pesanan yang sama dua kali — jumlah Energy yang sama ke alamat yang sama, satu demi satu. Kunci otomatis tidak dapat membedakannya dari percobaan ulang: kedua permintaan tersebut identik byte demi byte, dan satu-satunya hal yang membedakannya adalah momen kedatangannya.

Tanpa kunci Anda sendiri, hasilnya tergantung pada jarak waktu di antara keduanya:

Jarak antara kedua permintaanApa yang terjadi
Di dalam jendela 1 detik yang samaPermintaan kedua dianggap sebagai pengulangan. Permintaan tidak dieksekusi: Anda mendapatkan 208 dan respons pesanan pertama, termasuk orderId. Tidak ada biaya yang dikenakan untuk itu
Terpisah lebih dari satu detikDua kunci berbeda — kedua pesanan dibuat dan keduanya dikenakan biaya

Jadi, jika Anda mengandalkan kunci otomatis, berikan jeda lebih dari satu detik antara dua pesanan yang identik, dan baca kode status: 208 berarti pesanan yang baru saja Anda kirim tidak dibuat.

Jeda adalah solusi sementara, bukan perbaikan tuntas. Itu memisahkan setiap permintaan, termasuk permintaan yang tidak pernah Anda maksudkan untuk diulang — percobaan ulang setelah waktu habis, klik ganda, pesan yang dikirim ulang oleh antrean Anda. Permintaan tersebut juga tiba lebih lambat dari jendela waktu, sehingga dibuat sebagai pesanan terpisah dan dikenakan biaya terpisah. Batas waktu respons endpoint ini adalah 10 detik, yang sudah jauh di luar jendela waktu: kunci otomatis tidak melindungi percobaan ulang yang terjadi setelah batas waktu terlampaui.

Kunci Anda sendiri menghilangkan tebakan, karena keputusan berpindah ke satu-satunya sisi yang tahu jawabannya:

Yang Anda lakukanYang Anda kirimHasil
Pesanan kedua yang benar-benar barunonce baruKunci baru — pesanan dibuat
Percobaan ulang pesanan yang hasilnya belum Anda ketahuinonce dari upaya pertamaKunci yang sama — 208, respons asli, tidak ada biaya kedua

Baris kedua adalah alasan keberadaan header ini, dan di situlah implementasi biasanya meleset: lihat catatan di bawah Cara membentuk kunci.

Kode Status HTTP untuk Permintaan Duplikat ​

Kode StatusNamaDeskripsi
200OKPesanan berhasil diproses (permintaan pertama)
208Already ReportedPesanan telah diproses sebelumnya, mengembalikan respons ter-cache
409ConflictPermintaan sedang diproses, jangan coba lagi

Permintaan Duplikat - Sudah Diproses (208) ​

Saat permintaan duplikat diterima untuk pesanan yang sudah selesai:

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 2.54 TRX deducted",
        "data": {
            "hash": "9e4c20e21e01e4c39b21b670d1ea1fc1e4b0de94d8fbd4c190d5378ba911dfae",
            "energy": 65050,
            "orderId": "1H70bcc7962a",
            "paidTRX": 2.535,
            "delegateAddress": "TNp5gsJhBmZFXgCdgjMgr8pEZ8fHgXUHDq"
        }
    },
    "idempotency": {
        "status": "completed",
        "cached": true,
        "original_created_at": "2025-12-03T10:34:49.104896"
    }
}

Badan respons identik dengan respons sukses asli, dengan tambahan objek idempotency yang menunjukkan bahwa ini adalah respons yang di-cache.

Permintaan Duplikat - Masih Diproses (409) ​

Saat permintaan duplikat tiba ketika permintaan asli masih diproses:

json
{
    "success": false,
    "error": "duplicate_request_processing",
    "message": "This request is currently being processed. Please wait and do not retry.",
    "idempotency_key": "b9e67b2412d33c92a4f0e1c3d5b7a9f2e4c6d8b0a2f4e6c8d0b2a4f6e8c0d2b4",
    "retry_after_seconds": 3
}

Rekomendasi: Tunggu selama retry_after_seconds yang ditentukan sebelum memeriksa status pesanan.

Praktik Terbaik ​

  • Jangan mengirim permintaan paralel dengan parameter yang sama - tunggu setiap respons
  • Gunakan nonce baru untuk setiap pesanan baru, dan nonce upaya pertama untuk setiap percobaan ulangnya
  • Jangan pernah membuat ulang nonce pada saat pengiriman — percobaan ulang harus mereproduksi kunci upaya pertama, bukan kunci baru
  • Tangani respons 409 dengan menunggu, bukan dengan langsung mencoba lagi
  • Periksa bidang idempotency.cached untuk mengidentifikasi respons yang di-cache — 208 berarti pesanan yang baru saja Anda kirim tidak dibuat

Akun Pascabayar ​

Akun pada penagihan pascabayar menggunakan endpoint, URL, header, dan badan permintaan yang sama seperti yang lain. Perbedaannya adalah cara pembayaran pesanan:

  • Tidak ada yang dipotong dari deposit Anda. Setiap pesanan yang berhasil ditambahkan ke saldo tagihan akun Anda dalam mata uang penyelesaian yang disepakati dalam kontrak Anda. Anda membayarnya melalui faktur, sesuai perjanjian Anda.
  • Akun Anda memiliki batas kredit. Selama jumlah jatuh tempo berada dalam batas tersebut, pesanan diterima bahkan dengan deposit nol.
  • Hanya layanan yang dikirimkan yang ditagih. Pesanan yang ditolak atau tidak dieksekusi tidak dikenakan biaya apa pun.
  • Jika alamat penerima harus diaktifkan, aktivasi tersebut merupakan bagian dari pesanan yang sama dan ditagih sebagai biaya terpisah.

Penagihan pascabayar diaktifkan oleh Netts untuk akun berdasarkan permintaan. Setiap respons memberi tahu Anda bagaimana pesanan dibayar: paymentMode bernilai postpaid atau prepaid.

Bidang permintaan tambahan ​

ParameterTipeDiperlukanDeskripsi
testbooleanTidaktrue — hanya menghitung harga. Tidak ada yang dipesan, dikirim, atau ditagih
freezePricebooleanTidaktrue — mengunci harga berdasarkan kontrak Anda selama 60 detik. Tidak ada yang dipesan atau ditagih
quoteIdstringTidakBuat pesanan dengan harga dari penawaran yang diterbitkan oleh freezePrice
priceCurrencystringTidakTRX (default) atau mata uang kontrak Anda, seperti dalam settlement.asset. Untuk akun pascabayar, jumlah dalam mata uang kontrak Anda selalu disertakan

quoteId tidak dapat digabungkan dengan test atau freezePrice. Bidang lain apa pun di badan permintaan akan ditolak.

Pemeriksaan harga (test: true) ​

json
{
    "amount": 65000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "test": true
}
json
{
    "detail": {
        "code": 10010,
        "msg": "Test calculation",
        "data": {
            "amount": 65000,
            "unitPriceSun": "20",
            "discount": null,
            "energyTRX": "1.300000",
            "activationTRX": "1.100000",
            "wouldCostTRX": "2.400000",
            "paidTRX": 0,
            "paymentMode": "postpaid",
            "activationCheck": "inactive",
            "alt": {"USDC": {"energy": "0.430541", "activation": "0.364304", "total": "0.794845"}},
            "fxAt": "2026-10-19T07:15:18.469870+00:00"
        }
    }
}
BidangDeskripsi
unitPriceSunHarga per unit Energy dalam SUN, termasuk diskon pribadi Anda jika memilikinya
discountDiskon pribadi Anda (type, value) atau null
energyTRX / activationTRX / wouldCostTRXEnergy, aktivasi (jika alamat memerlukannya) dan total, dalam TRX
activationCheckinactive — alamat akan diaktifkan dan ditagih; active — tidak ada aktivasi; unknown — tidak dapat diperiksa saat ini
alt.<currency>Jumlah yang sama dalam mata uang kontrak Anda
fxAtWaktu nilai tukar yang digunakan untuk jumlah dalam mata uang kontrak Anda

Penawaran harga tetap (freezePrice: true) ​

Gunakan penawaran untuk mengunci harga berdasarkan kontrak Anda sebelum Anda memesan.

  1. Kirim pesanan dengan "freezePrice": true. Respons memiliki kode 10011 (Quote issued), bidang yang sama seperti pemeriksaan harga, ditambah quoteId dan expiresAt.
  2. Dalam waktu 60 detik kirim pesanan dengan "quoteId": "<quoteId>" dan amount serta receiveAddress yang sama.
  3. Pesanan ditagih pada harga penawaran — harga berdasarkan kontrak Anda pada saat penawaran diberikan — bahkan jika harga berubah di antaranya.

Penawaran dapat digunakan sekali dan hanya untuk produk yang sama: penawaran 1 jam tidak dapat membayar pesanan 5 menit. Penawaran yang kedaluwarsa atau sudah digunakan akan ditolak dan tidak ada yang dipesan.

json
{
    "amount": 65000,
    "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "quoteId": "q_4f540f16a2c94b7f8e3d1a6b5c0e9d72"
}

Pesanan berhasil ​

json
{
    "detail": {
        "code": 10000,
        "msg": "Successful, 1.30 TRX for energy + 1.10 TRX for address activation, postpaid",
        "data": {
            "orderId": "1Hf9544a1508",
            "paidTRX": 2.4,
            "hash": "032bda8fa6911b42c15a6d8d30520dc22bcc4077972a1503b6a3fae491967eb4",
            "delegateAddress": "TVnkj2jHKgmea8DVJFo2teD7rRSpH51bne",
            "energy": 65000,
            "activationHash": "259e1ab276114ae717a6f62d7d25eb1f89a2dccb637cbe41be626df3c2a78519",
            "paymentMode": "postpaid",
            "energyTRX": "1.300000",
            "activationTRX": "1.100000",
            "totalTRX": "2.400000"
        }
    }
}
BidangDeskripsi
paidTRXBiaya layanan dalam TRX. Untuk akun pascabayar ini tidak dipotong dari deposit
paymentModepostpaid
energyTRX / activationTRX / totalTRXJumlah pasti, 6 tempat desimal
quoteId, altAda ketika pesanan dibuat dengan penawaran: ID penawaran dan jumlah penawaran
activationFinalAda dan bernilai false hanya jika jumlah aktivasi bersifat sementara; jumlah akhir muncul di faktur Anda

Semua bidang lainnya sama seperti 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 ditagih. Pesanan baru akan diterima kembali setelah pembayaran Anda terdaftar atau batas Anda ditingkatkan.

Kode kesalahan pascabayar ​

KodeHTTPDeskripsi
10010200Hasil pemeriksaan harga (test)
10011200Penawaran diterbitkan (freezePrice)
1004402Batas kredit pascabayar tercapai
4100400Permintaan tidak valid
4101400priceCurrency tidak didukung
4102400quoteId digabungkan dengan test atau freezePrice
4103409Penawaran sudah digunakan
4104409Penawaran kedaluwarsa
4105409Kunci idempotensi sudah digunakan untuk permintaan yang berbeda
4106404Penawaran tidak ditemukan
4107409Parameter pesanan berbeda dari penawaran
4108400Format quoteId tidak valid
4109422Tidak tersedia untuk sub-akun
5032503Harga sementara tidak tersedia
5033503Nilai tukar sementara tidak tersedia
5034503Penagihan sementara tidak tersedia — pesanan tidak diterima
5036503Pemeriksaan kredit sementara tidak tersedia — coba lagi nanti

Untuk semua respons 4xx dan 503 di atas tidak ada yang dipesan dan tidak ada yang ditagih.

Catatan ​

  • Energy dikirimkan secara instan setelah pesanan berhasil (biasanya dalam 0,5-10 detik)
  • Batas waktu respons API: Maksimum 10 detik, biasanya merespons hingga 2 detik
  • Aktivasi alamat: Jika alamat penerima belum aktif, Netts mengaktifkannya sesuai harga modal
  • Keterlambatan aktivasi: Untuk alamat yang belum diaktifkan, respons API mungkin memerlukan waktu hingga 6 detik karena proses aktivasi
  • Pesanan diproses 24/7 dengan failover penyedia otomatis
  • Jumlah Energy minimum: 61.000 unit
  • Jumlah Energy maksimum: 3.000.000 unit per pesanan
  • Buffer Energy: +50 unit ditambahkan secara otomatis untuk kompensasi penyedia (bebas biaya)
  • Hash transaksi: Bidang selalu ada tetapi mungkin kosong jika penyedia tidak langsung mengembalikannya. Untuk mengambil hash, panggil /apiv2/order_check paling cepat 1 menit setelah membuat pesanan
  • Pemilihan penyedia: Otomatis berdasarkan biaya dan ketersediaan
  • Format ID pesanan: 1H{request_id} untuk pelacakan terpadu
  • Harga: Dinamis berdasarkan waktu hari dan jumlah Energy
  • Durasi: Tetap 1 jam (3600 detik)
  • Pembatasan laju: 50 permintaan per detik per alamat IP