Appearance
POST /apiv2/order1h
Buat pesanan sewa Energy 1 jam melalui beberapa penyedia Energy dengan failover otomatis.
URL Endpoint
POST https://netts.io/apiv2/order1hHeader 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 |
Body Permintaan
json
{
"amount": 131000,
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}Parameter
| Parameter | Tipe | Diperlukan | Deskripsi |
|---|---|---|---|
| amount | integer | Ya | Jumlah Energy yang akan disewa (minimum: 61000, maksimum: 3000000) |
| receiveAddress | string | Ya | Alamat 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 mencukupi
- Keandalan - Menggunakan penyedia dengan tingkat keberhasilan tinggi
- Kecepatan - Memprioritaskan waktu pengiriman tercepat
Contoh Permintaan
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 Berhasil (200 OK)
json
{
"detail": {
"code": 10000,
"msg": "Successful, 2.23 TRX deducted",
"data": {
"orderId": "1H123456",
"paidTRX": 2.23,
"hash": "a1b2c3d4e5f6789...",
"delegateAddress": "TDelegatePoolAddress...",
"energy": 131050
}
}
}Bidang Respons
| Bidang | Tipe | Deskripsi |
|---|---|---|
| detail.code | integer | Selalu 10000 untuk pesanan yang berhasil |
| detail.msg | string | Pesan keberhasilan dengan jumlah yang dipotong |
| detail.data.orderId | string | ID pesanan terpadu (format: 1H{request_id}) |
| detail.data.paidTRX | number | Total biaya dalam TRX (termasuk biaya aktivasi jika alamat belum diaktifkan) |
| detail.data.hash | string | null | Hash transaksi. Bidang selalu ada tetapi mungkin kosong - beberapa penyedia tidak langsung mengembalikan hash. Gunakan /apiv2/order_check setelah 1 menit untuk mendapatkan hash |
| detail.data.delegateAddress | string | Alamat pool yang mendelegasikan Energy |
| detail.data.energy | integer | Jumlah Energy + buffer (biasanya +50) |
Respons Kesalahan
Kesalahan Autentikasi (401)
json
{
"detail": "Invalid API key or IP not in whitelist"
}Saldo Tidak Mencukupi (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
| Kode | Deskripsi | Status HTTP |
|---|---|---|
10000 | Berhasil | 200 |
10000 | Berhasil (respons ter-cache) | 208 |
- | Permintaan duplikat masih diproses | 409 |
1004 | Saldo tidak mencukupi | 403 |
5000 | Kesalahan server internal | 500 |
5001 | Penyedia Energy tidak tersedia | 503 |
5002 | Penyedia Energy tidak tersedia | 503 |
5003 | Layanan Energy tidak tersedia | 503 |
5004 | Minimum penyedia Energy tidak terpenuhi | 503 |
Batas Laju
Batas laju berikut berlaku untuk endpoint ini (per alamat IP):
| Periode | Batas | Deskripsi |
|---|---|---|
| 1 detik | 50 permintaan | Maksimum 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: 49Batas Laju Terlampaui (429)
json
{
"message": "API rate limit exceeded"
}Idempotensi
API mendukung idempotensi untuk mencegah pemrosesan pesanan duplikat. Ketika 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 secara tidak sengaja mengirim permintaan yang sama dua kali, Anda tidak akan dikenakan biaya dua kali.
Menyediakan Kunci Anda Sendiri
Anda dapat mengelola idempotensi sendiri dengan mengirimkan header X-Idempotency-Key. Jika ada, nilai itu saja yang menentukan apakah suatu permintaan merupakan pengulangan, dan kombinasi otomatis di atas tidak digunakan. Jika tidak ada, tidak ada yang berubah — server menghasilkan kunci tersebut untuk Anda.
| Header | X-Idempotency-Key |
| Format | Tepat 64 karakter heksadesimal huruf kecil — intisari SHA-256 |
| Masa berlaku | 24 jam sejak permintaan pertama yang membawa kunci tersebut |
| Cakupan | Akun Anda. Nilai yang sama yang dikirim oleh akun berbeda tidak pernah mengembalikan hasil Anda |
Kunci dengan format lain apa pun — UUID dengan tanda hubung, base64, hex huruf besar — akan ditolak dengan 400 sebelum pesanan dibuat dan sebelum biaya apa pun dikenakan:
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 intisari hex 64 karakter, sehingga kode pembuatan kunci yang disalin dari endpoint tersebut akan mengembalikan 400 di sini.
Cara membentuk kunci
Turunkan dari kunci API Anda. Hal itu membuat nilainya unik untuk akun Anda, dapat direproduksi pada percobaan ulang, dan mustahil ditebak 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()
noncemilik pesanan, bukan milik permintaan. Tentukan sekali, saat pesanan dibuat di pihak Anda, dan teruskan nilai yang sama pada setiap pengiriman pesanan tersebut — baik upaya pertama maupun setiap percobaan ulang. Menghasilkan nilai baru di dalam fungsi pengiriman (str(uuid.uuid4())pada setiap pemanggilan) memberikan kunci yang berbeda pada setiap upaya, sehingga percobaan ulang setelah timeout diterima sebagai pesanan kedua dan dikenai biaya lagi. Pilihan benar yang paling sederhana adalah id pesanan yang sudah Anda miliki: ia sudah ada sebelum upaya pertama dan bertahan dari mulai ulang proses Anda.
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,
}Sebuah kunci aktif selama 24 jam. Setelah itu nonce yang sama bebas kembali dan memulai pesanan baru.
Jangan gunakan nilai yang bisa ditebak orang lain — 64 angka nol, intisari dari kata tetap. Kunci berbagi satu ruang lintas akun. Tabrakan seperti itu tidak pernah mengungkap 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, berturut-turut. Kunci otomatis tidak dapat membedakannya dari percobaan ulang: kedua permintaan tersebut identik secara bita demi bita, dan satu-satunya hal yang membedakannya adalah waktu kedatangannya.
Tanpa kunci Anda sendiri, hasilnya tergantung pada jeda di antara keduanya:
| Jeda antara kedua permintaan | Apa yang terjadi |
|---|---|
| Di dalam jendela 1 detik yang sama | Permintaan kedua dianggap sebagai pengulangan. Permintaan tidak dieksekusi: Anda mendapatkan 208 dan respons pesanan pertama, termasuk orderId. Tidak ada biaya yang dikenakan untuk itu |
| Lebih dari satu detik terpisah | Dua kunci berbeda — kedua pesanan dibuat dan keduanya dikenakan biaya |
Jadi, jika Anda mengandalkan kunci otomatis, beri jarak lebih dari satu detik antara dua pesanan identik, dan baca kode statusnya: 208 berarti pesanan yang baru saja Anda kirim tidak diproses.
Jeda adalah solusi sementara, bukan perbaikan tuntas. Ini memisahkan setiap permintaan, termasuk permintaan yang tidak pernah ingin Anda ulangi — percobaan ulang setelah timeout, 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 secara terpisah. Batas waktu respons endpoint ini adalah 10 detik, yang sudah jauh di luar jendela: kunci otomatis tidak melindungi percobaan ulang yang menyusul setelah timeout.
Kunci Anda sendiri menghilangkan perkiraan tersebut, karena keputusan berpindah ke satu-satunya pihak yang mengetahui jawabannya:
| Yang Anda lakukan | Yang Anda kirim | Hasil |
|---|---|---|
| Pesanan kedua yang benar-benar baru | nonce baru | Kunci baru — pesanan dibuat |
| Percobaan ulang pesanan yang hasilnya tidak Anda ketahui | nonce dari upaya pertama | Kunci 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 Status | Nama | Deskripsi |
|---|---|---|
| 200 | OK | Pesanan berhasil diproses (permintaan pertama) |
| 208 | Already Reported | Pesanan sudah diproses, mengembalikan respons ter-cache |
| 409 | Conflict | Permintaan sedang diproses, jangan coba lagi |
Permintaan Duplikat - Sudah Diproses (208)
Ketika 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"
}
}Isi respons identik dengan respons awal yang berhasil, dengan tambahan objek idempotency yang menunjukkan bahwa ini adalah respons ter-cache.
Permintaan Duplikat - Masih Diproses (409)
Ketika permintaan duplikat tiba saat 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": "b9e67b2412d33c92...",
"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
noncebaru untuk setiap pesanan baru, dannonceupaya pertama untuk setiap percobaan ulangnya - Jangan pernah membuat ulang
noncepada 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.cacheduntuk mengidentifikasi respons ter-cache —208berarti pesanan yang baru saja Anda kirim tidak diproses
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 diaktifkan, Netts mengaktifkannya dengan harga pokok
- Penundaan 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 - Penetapan harga: Dinamis berdasarkan waktu dan jumlah Energy
- Durasi: Tetap 1 jam (3600 detik)
- Pembatasan laju: 50 permintaan per detik per alamat IP