Permintaan pertama: cek saldo
GET{ "balance": 150000 }
Satu kunci API untuk seluruh layanan: pembayaran QRIS, produk digital premium, media sosial (SMM), sewa nomor OTP, dan database SQL. Ganti setiap {placeholder} dengan nilai sebenarnya, dan pertahankan tipe JSON seperti string, angka, boolean, atau null.
Quickstart, autentikasi, bentuk respons, batas laju, dan aturan retry sebelum memakai endpoint mana pun.
GET /api/v1/balance dengan header X-API-Key. Apabila respons berisi angka saldo, kunci tersebut masih berlaku.Contoh di bawah ini dapat disalin langsung. Setiap kartu endpoint di halaman ini memiliki tab cURL, JavaScript, Python, dan PHP yang dibuat otomatis dari definisi endpoint yang sama.
{ "balance": 150000 }
Semua endpoint memerlukan header X-API-Key atau parameter kueri apikey.
X-API-Key: {api_key}
Buat, lihat, dan ganti API Key di halaman Profil pada bagian Keamanan & Integrasi. Jaga kerahasiaannya dan gunakan header autentikasi; parameter kueri mudah tersimpan di log server dan riwayat peramban.
401 tanpa header berarti kunci tidak dikirim; 401 dengan header berarti kunci tidak ditemukan atau sudah dirotasi; 403 berarti kunci valid tetapi akun sedang dinonaktifkan admin; kunci yang hilang menimbulkan notifikasi ke pemilik akun, sehingga periksa kotak masuk sebelum menyangka integrasi rusak.
Sukses: setiap layanan membalas JSON dengan bentuknya sendiri: { "balance": 150000 } untuk saldo, { "success": true, ... } untuk pesanan dan operasi. Contoh lengkapnya ada di kartu tiap endpoint.
Gagal: seluruh endpoint membalas { "error": "pesan" }. Endpoint OTP menyertakan tambahan reason berupa kode penyebab yang stabil (out_of_stock, price_changed, insufficient_balance, rate_limited, provider_down, dll.).
reason, bukan pada teks pesan. Pesan error ditujukan untuk manusia dan bisa berubah sewaktu-waktu; kode status dan reason adalah kontraknya.| Kode | Makna | Tindakan |
|---|---|---|
| 400 | Parameter tidak valid atau permintaan ditolak. | Periksa nama, tipe, dan format nilai sesuai contoh endpoint. |
| 401 | API Key tidak dikirim, salah, atau sudah dirotasi. | Salin ulang kunci dari halaman Profil. |
| 402 | Saldo tidak cukup untuk pesanan/pencairan ini. | Deposit, lalu ulangi permintaan identik. |
| 403 | Kunci valid, tetapi akun dinonaktifkan. | Hubungi admin; jangan diulang otomatis. |
| 404 | Sumber daya tidak ada atau bukan milik Anda. | Periksa ID; jangan diulang tanpa perubahan. |
| 409 | Konflik status: harga berubah, aksi tidak berlaku pada status saat ini, atau guard batch gagal. | Ikuti isi pesan; muat ulang katalog lalu coba lagi. |
| 413 | Ukuran file/data melebihi batas yang diizinkan. | Perkecil unggahan. |
| 429 | Batas laju terlampaui. | Tunggu sesuai header Retry-After (detik). Jangan menebak jeda dari isi pesan. |
| 500 | Kesalahan server tak terduga. | Ulangi nanti dengan backoff; periksa /health bila berlanjut. |
| 502 | Layanan tidak dapat dijangkau. | Ulangi dengan backoff; saldo Anda tetap utuh. |
| 503 | Layanan sedang gangguan atau belum dikonfigurasi. | Ulangi nanti; saldo Anda tetap utuh. |
Saldo tidak pernah dipotong bila permintaan gagal sebelum pesanan terbentuk; apabila kegagalan terjadi di tengah (pesanan ditolak di sistem, koneksi putus), pengembalian dilakukan otomatis. Tidak ada tagihan yang perlu ditagih sendiri.
| Layanan | Batas | Catatan |
|---|---|---|
| Jaring global | 600 / menit / IP | Berlaku untuk seluruh permintaan sebagai jaring pengaman. |
| Payment & Premium | 120 / menit / IP | Rute /api/v1 dan /api/prem. |
| SMM | 60 / menit / API Key | Pemesanan dibatasi 30/menit; 300/menit/IP. |
| OTP | 60 / menit / API Key | Pemesanan dibatasi 20/menit; 300/menit/IP. |
| DongtubeDB | 600 / menit / API Key | Bawaan, dapat disesuaikan oleh pengelola (DONGTUBEDB_API_RPM). |
Retry-After dalam detik, termasuk saat pembatas datang dari sistem kami sendiri, yang diteruskan apa adanya. Hormati nilainya sebelum mengulang.GET) aman diulang kapan saja. Untuk permintaan tulis, lihat bagian Idempotensi; jangan mengulang membabi buta setelah timeout.429 diteruskan apa adanya beserta header Retry-After-nya; hormati nilainya, jangan diabaikan.Permintaan pembuatan pesanan yang identik di dalam jendela 90 detik membalas duplicate: true beserta pesanan yang sudah ada: saldo tidak dipotong dua kali. Ini berlaku untuk POST /api/smm/order, POST /api/otp/order, dan POST /api/prem/order (juga klik ganda pada aktifkan kembali nomor OTP).
| Situasi | Boleh diulang? | Cara aman |
|---|---|---|
| Timeout / putus setelah kirim | Pesanan belum tentu gagal. | Tarik status dulu (GET daftar pesanan / status invoice) sebelum membuat baru. |
429 | Ya. | Tunggu Retry-After, lalu kirim ulang identik. |
502 / 503 | Ya, dengan backoff. | Permintaan biasanya gagal sebelum saldo dipotong; jendela duplikat 90 detik ikut melindungi. |
400 / 409 | Tidak otomatis. | Perbaiki isi permintaan sesuai pesan, baru kirim ulang. |
Pencairan dana bersifat idempoten per ID pencairan, dan webhook invoice hanya dikirim untuk peristiwa lunas yang sebenarnya. Pengulangan pemeriksaan status tidak pernah menggandakan uang. Pencairan saldo lewat API diproses manual oleh admin: buat satu permintaan, tunggu persetujuan, jangan kirim ulang.
Permintaan uji dikirim dari peramban langsung ke API Dongtube menggunakan API Key yang dimasukkan. Jangan gunakan konsol ini pada perangkat bersama.
Deposit, pemeriksaan saldo, serta pembuatan dan pemantauan invoice QRIS.
Mengembalikan saldo akun yang terkait dengan API Key.
{ "balance": 0 }
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| amount | number | Ya | Nominal invoice dalam Rupiah. |
{
"success": true,
"type": "dynamic",
"invoice_id": "{invoice_id}",
"amount": 0,
"fee": 0,
"total": 0,
"qris_image": "{qris_image_url}",
"expired_at": "{expiration_time}"
}
Nilai qris_image berisi path gambar QRIS relatif terhadap origin situs (contoh /img-cache/qris-1234567890.png); gabungkan dengan origin situs untuk memperoleh URL lengkapnya. Pembuatan invoice dibatasi 30 kali per menit.
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| invoice_id | string | Ya | ID dari respons pembuatan invoice. |
{
"invoice_id": "{invoice_id}",
"amount": 0,
"fee": 0,
"total": 0,
"status": "{invoice_status}",
"qris_image": "{qris_image_url}",
"expired_at": "{expiration_time}",
"created_at": "{created_at}"
}
Status memberi tahu apakah pembayaran masih menunggu, sudah dibayar, atau sudah kedaluwarsa. Polling endpoint ini aman diulang: pemeriksaan berulang tidak pernah menggandakan tagihan.
Atur URL webhook di halaman Profil. Apabila deposit lunas, sistem mengirim POST JSON ke URL tersebut. Verifikasi kebenaran melalui header X-Signature = sha256=HMAC-SHA256(body, API Key) terhadap body mentah, bukan hasil parse ulang JSON. Balas 2xx untuk konfirmasi penerimaan; gagal atau timeout dicoba ulang 1x.
// Body yang dikirim ke URL Anda
{
"event": "invoice.paid",
"invoice_id": "{invoice_id}",
"amount": 0,
"fee": 0,
"total": 0,
"status": "paid",
"paid_at": "{payment_time}"
}
// Verifikasi (Node.js), hash body MENTAH, bukan hasil parse
const crypto = require('crypto');
const expected = 'sha256=' + crypto
.createHmac('sha256', API_KEY)
.update(rawBody)
.digest('hex');
if (expected !== req.headers['x-signature']) return res.sendStatus(401);
GET /api/v1/invoice/status selalu menjadi sumber kebenaran. Apabila webhook terlewat (server down), tetapkan status dari polling. Jangan pernah menarik uang atau membuka akses hanya karena asumsi webhook pasti diterima.Pencairan saldo ke rekening bank atau e-wallet. Pada API, operasi ini bernama topup.
account_name pada langkah terakhir harus berasal dari respons inquiry: server memverifikasi ulang nama tujuan saat dana dikirim, jadi nama karangan akan membuat pencairan ditolak dan saldo otomatis dikembalikan. Pengguna juga bisa memakai halaman Tarik Saldo; keduanya memakai saldo dan biaya yang sama.
Langkah pertama dan wajib dipanggil setiap kali membangun form pencairan. Tidak ada parameter. Mengembalikan daftar e-wallet beserta batas nominal per e-wallet, daftar kode bank, biaya admin yang berlaku, serta batas nominal bank.
{
"success": true,
"fee": 2500,
"ewallet": [
{ "code": "DANA", "name": "DANA", "min": 20000, "max": 2000000 },
{ "code": "GOPAY", "name": "GoPay", "min": 10000, "max": 2000000 },
{ "code": "OVO", "name": "OVO", "min": 10000, "max": 2000000 },
{ "code": "LINKAJA", "name": "LinkAja", "min": 10000, "max": 2000000 },
{ "code": "SHOPEEPAY", "name": "ShopeePay", "min": 10000, "max": 2000000 }
],
"bank": [
{ "code": "008", "name": "Mandiri" },
{ "code": "009", "name": "BNI" },
{ "code": "002", "name": "BRI" }
],
"bank_min": 10000,
"bank_max": 50000000
}
Nilai code inilah yang nanti dikirim sebagai code pada langkah inquiry dan topup. Daftar bank memuat kode virtual account dan katalog bank nasional, jadi ratusan kode tersedia, jangan di-hardcode, ambil dari endpoint ini.
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| type | string | Tidak | bank (bawaan) atau ewallet. |
| code | string | Ya | Kode dari methods. Untuk e-wallet berarti kode produk (DANA, GOPAY, dst). |
| account | string | Ya | Nomor rekening atau nomor e-wallet tujuan. |
| amount | number | Tidak | Nominal yang dipindahkan ke tujuan. Bawaan mengikuti minimum pencairan akun. |
Baca-saja dan tidak menggerakkan uang: pemanggilan ini tidak memotong saldo. Wajib dipanggil lebih dulu untuk memperoleh account_name, yang lalu dikirim apa adanya ke endpoint topup. Tampilkan hasilnya ke pengguna sebagai konfirmasi sebelum konfirmasi pencairan.
{
"success": true,
"type": "bank",
"account_name": "NAMA PEMILIK REKENING",
"provider": "Bank Mandiri"
}
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
| type | string | Tidak | bank (bawaan) atau ewallet. |
| code | string | Ya | Kode tujuan dari methods. |
| account | string | Ya | Nomor rekening atau e-wallet tujuan. |
| account_name | string | Ya | Harus sama dengan hasil inquiry. |
| amount | number | Ya | Nominal yang dikirim ke tujuan, tanpa biaya admin. |
{
"success": true,
"status": "pending",
"amount": 50000,
"fee": 2500,
"account_name": "NAMA PEMILIK REKENING"
}
Langkah terakhir membuat permintaan pencairan: status mengembalikan pending (permintaan menunggu persetujuan admin), bukan dana yang langsung dikirim. Saldo amount + fee sudah dipotong saat permintaan dibuat dan akan kembali penuh bila admin menolak.
Perhatikan jumlah yang dipotong dari saldo. Saldo dipotong sebesar amount + fee, bukan amount. Jadi untuk mencairkan Rp50.000 ke tujuan dengan biaya Rp2.500, saldo harus tersedia Rp52.500.
| Jenis | Minimum | Maksimum | Keterangan |
|---|---|---|---|
| DANA | Rp 20.000 | Rp 2.000.000 | Minimum e-wallet tertinggi. |
| E-wallet lainnya | Rp 10.000 | Rp 2.000.000 | GoPay, OVO, LinkAja, ShopeePay. |
| Bank | Rp 10.000 | Rp 50.000.000 | Nomor di luar rentang dijawab 400. |
Minimum aktual bisa lebih besar bila pengaturan minimum pencairan akun lebih tinggi. Selalu baca nilai min, max, bank_min, dan bank_max dari endpoint methods, jangan angka tetap.
fee pada respons methods.account_name apa adanya dari respons inquiry.failed.| Status | Makna | Tindakan integrator |
|---|---|---|
| success | Admin sudah menyetujui dan dana dikirim manual ke tujuan. | Berhenti memantau, tampilkan selesai ke pengguna. |
| pending | Permintaan diterima, menunggu persetujuan admin (biasanya < 1×24 jam). | Tahan status "diproses". Jangan kirim ulang permintaan. |
| failed | Admin menolak permintaan. Saldo plus biaya dikembalikan penuh. | Tampilkan gagal; saldo pengguna sudah kembali. |
success/pending pada respons topup, atau pengguna membuka riwayat pencairan di dashboard.
Memilih layanan, membuat pesanan media sosial, memantau status, dan mengajukan isi ulang.
X-API-Key dan menarik saldo dari akun yang sama dengan halaman Dongtube SMM. Kredensial penghubung hanya berada di server dan tidak pernah dikirim ke peramban.duplicate: true tanpa memotong saldo lagi.503 dan saldo tetap utuh.| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| q | string | Tidak | Pencarian nama layanan. |
| category | string | Tidak | Filter kategori. |
| type | string | Tidak | Filter tipe layanan (lihat tabel per tipe). |
{
"success": true,
"count": 2250,
"services": [
{
"id": "1234",
"name": "{nama_layanan}",
"category": "{kategori}",
"type": "default",
"type_label": "Standar",
"price_mode": "per_1000",
"price_per_1000": 11512,
"min_price": 117,
"min": 10,
"max": 300000,
"refill": false,
"fields": [
{ "key": "target", "required": true, "label": "Target layanan", "input": "text", "hint": "..." },
{ "key": "quantity", "required": true, "label": "Jumlah pesanan", "input": "number" }
],
"target_format": { "kind": "url", "label": "link channel, grup, atau post", "contoh": "https://t.me/contoh" },
"description": "{deskripsi}"
}
]
}
Katalog berisi lebih dari 2.000 layanan, simpan cadangan di sisi Anda karena isinya jarang berubah. price_per_1000 adalah harga per 1.000 unit, atau harga total apabila price_mode bernilai total. min_price adalah biaya yang benar-benar dibebankan untuk memesan sesuai min. Keduanya adalah harga final. fields menyebutkan parameter beserta batas karakter yang diterima; kirim hanya field bertanda required.
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
| service_id | string | Ya | ID layanan dari katalog. |
| target | string | Ya | Tautan atau identitas akun sesuai layanan. |
| quantity | number | Ya* | *Tidak dikirim bila memakai comments. |
| comments | string | Ya* | Satu komentar per baris; jumlah dihitung otomatis. |
{
"success": true,
"order": {
"id": "{order_id}",
"service_id": "1234",
"service_name": "{nama_layanan}",
"category": "{kategori}",
"target": "{target}",
"quantity": 1000,
"amount": 11500,
"status": "pending",
"provider_order_id": "56789",
"provider_status": "Pending",
"refill": { "supported": false, "id": null, "status": null, "requested_at": null },
"refund": { "refunded": false, "amount": 0, "partial": false, "partial_amount": 0 },
"start_count": null,
"remains": null,
"created_at": "{tanggal}",
"updated_at": "{tanggal}"
},
"duplicate": false
}
Parameter limit bernilai 1-100 (bawaan 20). Hingga 5 pesanan terbaru yang masih berjalan disegarkan statusnya sebelum dibalas.
{
"success": true,
"count": 20,
"orders": [ { "id": "{order_id}", "status": "completed", "...": "..." } ]
}
Memakai ID internal pesanan. Apabila status masih pending atau processing, statusnya disegarkan langsung sehingga Anda tidak perlu menunggu pembaruan latar.
{
"success": true,
"order": {
"id": "{order_id}",
"status": "completed",
"quantity": 1000,
"amount": 11500,
"provider_status": "Completed",
"start_count": 0,
"remains": 0,
"refund": { "refunded": false, "amount": 0, "partial": false, "partial_amount": 0 }
}
}
Tidak ada isi permintaan. Hanya layanan bertanda refill: true dan pesanan berstatus completed/partial yang diterima. Pengajuan kembar dibalas dengan "reused": true beserta refill yang sedang berjalan.
{
"success": true,
"reused": false,
"refill_id": "555",
"refill_status": "pending",
"order_id": "66a1f0c2b3d4e5f6a7b8c9d0"
}
Selama refill_status masih pending/processing, setiap pemanggilan membaca status terbaru langsung dari sistem. Nilai: pending, processing, success, atau failed (terminal). Bila pengajuan ditolak, nilainya berisi catatan penolakan yang diawali ditolak:.
{
"success": true,
"refill_id": "555",
"refill_status": "success",
"refill_requested_at": "2026-09-27T08:33:37.056Z",
"order_status": "completed"
}
Kirim hanya parameter yang terdaftar untuk tipe tersebut; parameter lain diabaikan sistem. Tipe tersedia tercantum pada field type dalam respons katalog.
| Tipe | Parameter | Catatan |
|---|---|---|
| default | target, quantity | Standar untuk hampir seluruh katalog. |
| package | target | Jumlah terkunci pada nilai minimum. |
| custom_comment | target, comments | Satu komentar per baris; jumlah dihitung otomatis. |
| comment_reply | target, username, comments | Balasan ke akun tertentu. |
| comment_likes | target, quantity, username | Like pada komentar milik username. |
| mention_list | target, usernames | Satu username per baris. |
| mention_hastag | target, quantity, hashtag | Tanpa tanda #. |
| mention_follower | target, quantity, username | Menyebut pengikut milik username. |
| mention_media | target, quantity, media | Menyebut dari unggahan pada tautan media. |
| poll | target, quantity, answer_number | Pilih nomor jawaban yang didukung. |
Layanan bertanda refill: true dapat diajukan isi ulang setelah pesanan selesai. Untuk penjelasan lengkap, lihat panduan Dongtube atau FAQ Status Pesanan.
Sewa nomor sementara untuk menerima kode verifikasi dari berbagai layanan.
X-API-Key. Harga katalog dan pemotongan saldo mengikuti akun yang bersangkutan, persis seperti pemesanan lewat halaman web.Tidak ada isi permintaan. Respons memuat count, default, dan countries berisi { id, name, flag } untuk semua country_id yang diterima oleh /services dan /order. country_id tetap opsional (bawaan mengikuti pengaturan akun, mis. 7 = Indonesia).
Parameter opsional country_id (tanpa parameter memakai default akun). Katalog, harga, dan stok berbeda untuk tiap negara; daftar ID-nya ada di GET /api/otp/countries. Respons memuat success, country yang dipakai ({ id, name }), count, dan services: { service_code, service_name, product_id, price, stock, tiers } urut popularitas. service_code adalah ID platform layanan (contoh 1 = WhatsApp). Harga adalah harga final dalam Rupiah.
product_id menunjuk satu harga/tier pasti, dan tiers memuat SELURUH harga layanan itu di negara terpilih, { product_id, price, stock, operator, operator_id } urut harga menaik, termasuk yang stoknya sedang kosong (stock: 0). Kirim salah satu product_id itu ke /order untuk mengunci harganya. Tier price/stock/product_id di level layanan adalah harga termurah yang sedang berstok, sama dengan pemakaian tanpa product_id.
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| country_id | number | Ya | Dari /countries. |
| platform_id | number | Ya | Nilai service_code dari /services. |
Respons memuat count dan operators: { operator_id, code, name, local_name }. Daftar kosong berarti kombinasi itu memang tanpa pilihan carrier, pesanan tetap jalan tanpa operator_id (carrier dipilih otomatis).
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
| service_code | string | Ya | ID platform layanan, contoh 1 = WhatsApp. |
| country_id | number | Tidak | Bawaan negara pengaturan akun. Format lain dijawab 400. |
| qty | number | Tidak | 2-100 untuk memesan beberapa nomor sekaligus. |
| operator_id | number | Tidak | Mengunci satu carrier. Kosong berarti dipilih otomatis. |
| product_id | string / number | Tidak | Mengunci satu harga dari tiers di /api/otp/services. Kosong berarti harga termurah yang sedang berstok. |
| quoted_price | number | Tidak | Harga yang sedang Anda tampilkan, untuk mendeteksi perubahan harga. |
400 Layanan tidak tersedia.max_price sebesar amount yang Anda bayar, sehingga biaya tidak pernah melebihi penerimaan.reason: out_of_stock. Tidak ada harga lain yang dicoba diam-diam; muat ulang /api/otp/services lalu pesan ulang dengan harga lain yang dipilih.reason (kode penyebab, untuk ditindaklanjuti program) di samping error (pesan lengkap masalah + solusi, untuk ditampilkan ke pengguna). Nilai reason: out_of_stock (409), price_changed (409), not_found, harga hilang dari katalog (409), insufficient_balance (402), invalid_request (400/422), rate_limited (429 + header Retry-After), abuse_blocked (429, pembatasan sementara dengan retry_after_seconds), provider_account (503), provider_down (502), auth (503).error tidak pernah berupa teks mentah sistem maupun pesan generik selama reason ada.duplicate: true tanpa memotong saldo lagi.quoted_price, pesanan ditolak 409 dengan pesan Harga berubah dari Rp X menjadi Rp Y. tanpa memotong saldo, muat ulang katalog lalu ulangi.qty > 1, tiap baris pada order.orders yang ok: false memuat reason-nya sendiri. Begitu satu nomor ditolak karena stok habis (kondisi berlaku untuk layanan itu saat ini juga), sisa antrean langsung dihentikan agar tidak membakar panggilan percuma.| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
| limit | number | Tidak | 1-100, bawaan 20. |
| offset | number | Tidak | Paginasi, urutan terbaru lebih dulu. |
| status | string | Tidak | submitting|active|received|expired|cancelled|failed maupun gaya status mentah ACTIVE|OTP_RECEIVED|COMPLETED|CANCELED|EXPIRED. |
Respons memuat count, limit, offset, dan orders. Nilai status di luar daftar dijawab 400.
Selama pesanan berstatus active, endpoint ini membaca kode terbaru begitu SMS tiba: otp terisi dan status berubah menjadi received. Panggil berulang selama nomor masih menunggu.
Tidak ada isi permintaan. Hanya pesanan berstatus active yang dapat dibatalkan; status lain menjawab 409. Pembatalan terlalu dini ditolak dengan pesan kapan bisa dicoba lagi. Saldo dikembalikan penuh setelah pembatalan dikonfirmasi; SMS yang sudah diterima membuat pesanan tidak dapat dibatalkan.
Tidak ada isi permintaan. Hanya pesanan berstatus received yang bisa ditandai selesai; status lain menjawab 409. Setelah selesai, pesanan keluar dari daftar aktif, kode tetap terlihat di riwayat dan tidak ada pengembalian dana.
Tidak ada isi permintaan. Hanya berlaku selama pesanan masih berstatus active. Sistem dapat menahan pengiriman ulang sesaat setelah order dibuat, pesan penolakan berisi kapan bisa dicoba lagi. Respons memuat resent (bool): false berarti platform tersebut memang tidak mendukung pengiriman ulang.
Baca-saja dan tanpa biaya. Membalas available: true beserta cost (biaya dasar) dan price (harga yang dibebankan ke saldo Anda). Nomor yang tidak memenuhi syarat membalas available: false beserta alasannya.
Tidak ada isi permintaan. Mengaktifkan kembali nomor dari pesanan yang sudah selesai untuk verifikasi berikutnya, nomor sama, pesanan baru (saldo dipotong sesuai price dari pratinjau; bila biaya naik saat eksekusi, pesanan dibatalkan otomatis dan saldo kembali utuh). Hanya nomor yang memenuhi syarat; sisanya menjawab 409. Klik ganda dalam hitungan detik membalas duplicate: true.
503 dan saldo tetap utuh.{
"success": true,
"duplicate": false,
"order": {
"id": "66f1c2a4b9e7d3a5f8c2d1e0",
"country_id": "7",
"country_name": "Indonesia",
"service_code": "1",
"service_name": "WhatsApp",
"product_id": "1369642071",
"catalog_product_id": "450",
"phone_number": "6281234567890",
"otp": null,
"otp_message": null,
"expires_at_ms": 1780000000000,
"amount": 3934,
"status": "active",
"provider_status": "Nomor berhasil dipesan; menunggu OTP.",
"refunded": false,
"refund_amount": null,
"can_cancel": true,
"can_resend": true,
"can_replace": true,
"cancel_available_at": null,
"resend_available_at": null,
"replace_available_at": null,
"operator_id": null,
"created_at": "2026-09-28T08:00:00.000Z",
"updated_at": "2026-09-28T08:00:05.000Z"
}
}
| Field | Keterangan |
|---|---|
| id | ID internal pesanan. |
| country_id / country_name | Negara tujuan pesanan. |
| service_code / service_name | Platform tujuan, mis. 1 = WhatsApp. |
| product_id | Tier-slot katalog layanan. |
| catalog_product_id | Umbrella negara+platform yang dirutekan, satu-satunya yang dipakai saat pemesanan. |
| phone_number | Nomor untuk menerima kode OTP. |
| otp / otp_message | Terisi begitu SMS tiba. |
| expires_at_ms | Batas berlaku pesanan (ms epoch), lebih cepat antara batas sewa nomor dan batas keras 10 menit. |
| amount | Saldo yang dipotong. |
| status | submitting, active, received, expired, cancelled, failed. |
| provider_status | Keterangan status tambahan dari sistem. |
| refunded / refund_amount | Senilai amount bila dikembalikan. |
| can_cancel | Bisa dibatalkan selama status masih menunggu dan belum ada SMS masuk. |
| can_resend | Bisa minta SMS ulang selama menunggu. |
| can_replace | Bisa ganti nomor, syaratnya sama dengan pembatalan. |
| *_available_at | Waktu (ms epoch) aksi boleh dieksekusi saat masih menahan penangguhan; null = sudah bebas. |
| operator_id | Carrier yang dikunci; null = dipilih otomatis. |
| can_reactivate | Kandidat reaktivasi, nomor sudah menerima OTP. |
| can_finish / finished_at | Status dan waktu penandaan selesai. |
| sms_revision | Nomor urut SMS, dipakai mengabaikan SMS yang datang terlambat. |
Penyimpanan file online (CDN) plus database SQL personal.
X-API-Key. Kueri SQL, tabel, unggah file, dan pencadangan juga mensyaratkan langganan aktif dari halaman DongtubeDB; daftar/hapus file dan informasi penyimpanan tetap dapat diakses tanpa langganan.{
"plan": "{plan_name}",
"planLabel": "{plan_label}",
"storageLimit": 0,
"storageUsed": 0,
"storageAvailable": 0,
"expiresAt": "{expiration_time}"
}
Parameter limit (bawaan 20, maksimal 100) dan offset.
{
"success": true,
"total": 0,
"data": [{
"id": "{file_id}",
"originalName": "{file_name}",
"mimeType": "{mime_type}",
"size": 0,
"isPublic": false,
"downloads": 0,
"uploadedAt": "{upload_time}",
"cdnUrl": "{cdn_file_url}"
}]
}
Kirim sebagai multipart/form-data. Field wajib file; field opsional public (1 = publik, 0 = privat, bawaan 0). Data melebihi batas ukuran dijawab 413.
{ "success": true, "fileId": "{file_id}", "name": "{file_name}", "size": 0, "cdnUrl": "{cdn_file_url}" }
{ "success": true }
File publik: langsung diakses tanpa header, cocok untuk gambar di website. File privat: wajib menyertakan header X-API-Key.
Paket dan harga mengikuti pengaturan terbaru pada halaman DongtubeDB.
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
| sql | string | Ya | Satu pernyataan SQL. |
| params | array | Tidak | Nilai untuk placeholder ?, maksimal 500 elemen. |
// SELECT { "success": true, "rows": [...], "count": 1 } // INSERT / UPDATE / DELETE { "success": true, "changes": 1, "lastInsertRowid": 7 }
SELECT / INSERT / UPDATE / DELETE / CREATE TABLE / CREATE [UNIQUE] INDEX / DROP TABLE / DROP INDEX / ALTER TABLE.SELECT dibatasi maksimal 100.000 baris (bawaan). Sertakan LIMIT agar kueri tidak memotong hasil yang dibutuhkan.Semua pernyataan dijalankan dalam satu transaksi SQLite: perubahan diterapkan seluruhnya jika berhasil, atau dibatalkan bila terjadi kegagalan. Maksimal 100 pernyataan per batch.
expectChanges: true berarti: bila pernyataan tersebut mengubah 0 baris, transaksi dibatalkan dan server mengembalikan 409 { "guardFailed": true, "statementIndex": i }. Gunakan untuk memvalidasi kondisi sebelum perubahan, misalnya saldo mencukupi atau status masih menunggu. Respons sukses: { "success": true, "results": [...] }. last_insert_rowid() dapat dipakai pada pernyataan berikutnya di koneksi yang sama.
Operasi CRUD melalui /db/api/v2/:table/rows. Filter diberikan sebagai parameter kueri memakai operator eq neq gt gte lt lte like in is. Nama tabel dan kolom adalah identifier yang harus sesuai skema, bukan nilai yang dapat diikat sebagai parameter.
GET /db/api/v2/{table_name}/rows?{column_name}=eq.{value}&select={column_list}&order={column_name}.desc&limit={limit}&count=exact
POST /db/api/v2/{table_name}/rows body: {object_payload} | [{object_payload}, ...] (maksimal 1.000)
POST /db/api/v2/{table_name}/rows?on_conflict={column_name} (upsert)
PATCH /db/api/v2/{table_name}/rows?{column_name}=eq.{value} body: {changes_payload} (filter wajib)
DELETE /db/api/v2/{table_name}/rows?{column_name}=eq.{value} (filter wajib)
in: ?{column_name}=in.{value_1},{value_2}; is: ?{column_name}=is.null atau is.notnull.order={column_name}.asc|{column_name}.desc (boleh beberapa kolom dengan koma), limit maksimal 10.000, dan offset.count=exact menambahkan total pada respons.{ "success": true, "tables": [{ "name": "{table_name}", "rows": 0, "columns": 0 }], "count": 1 }
Parameter limit (bawaan 100, maksimum 1.000) dan offset.
{
"success": true,
"table": "{table_name}",
"schema": [{ "cid": 0, "name": "{column_name}", "type": "{data_type}", "pk": 0 }],
"rows": [{ "{column_name}": "{value}" }],
"total": 0,
"limit": 100,
"offset": 0
}
Nama tabel dibersihkan menjadi identifier (huruf, angka, garis bawah). Tabel yang tidak ada tetap dijawab sukses.
{ "success": true }
Tambahkan ?format=json untuk JSON. Secara default hasil diekspor sebagai file CSV. Maksimal 100.000 baris.
Tidak ada endpoint push, WebSocket dan SSE sudah dihapus. Klien mengikuti perubahan dengan menarik baris yang lebih baru dari kursor terakhir, lalu mengulanginya dengan interval yang menyesuaikan aktivitas.
// 1. Simpan updatedAt terakhir sebagai kursor cursor = 0 // 2. Tarik baris yang berubah sejak kursor GET /db/api/v2/{table_name}/rows?updatedAt=gt.{cursor}&select=key,value,updatedAt&order=updatedAt.asc&limit=1000 -> { "success": true, "rows": [ ... ], "count": 3 } // 3. Naikkan kursor ke updatedAt maksimum hasil, ulangi cursor = max(rows[].updatedAt)
POST /db/api/query dengan WHERE updatedAt > ? ORDER BY updatedAt LIMIT ?. Keduanya membalas JSON.kv, updatedAt adalah nomor urut penulisan yang dinaikkan trigger SQLite, selalu naik dan unik, sehingga aman dipakai sebagai kursor. Pada tabel lain kolom delta dikelola oleh aplikasi.Ekspor seluruh database (semua tabel dan data) ke satu file .db. File cadangan dapat dipulihkan ke akun yang sama atau akun lain dengan langganan aktif. Proses impor merupakan penggantian penuh: seluruh isi database tujuan akan diganti dengan isi file cadangan. Pencadangan juga tersedia melalui tab Impor/Ekspor di SQL Studio.
GET
File dongtubedb-backup-YYYY-MM-DD.db akan diunduh. Simpan file tersebut sebagai cadangan.
POST
Kirim file cadangan menggunakan multipart/form-data dengan field backup. File divalidasi (header SQLite dan pemeriksaan integritas) serta harus sesuai dengan kapasitas paket.
curl -X POST "https://{host}/db/api/backup/import" \
-H "X-API-Key: {api_key}" \
-F "backup=@{backup_file_path}"
Resep alur lengkap dari nol sampai selesai, dan riwayat perubahan kontrak API.
GET /api/v1/invoice?amount={amount}, lalu tampilkan qris_image ke pengguna.X-Signature atas body mentah) dan polling GET /api/v1/invoice/status sebagai jaring pengaman.paid berarti layanan dibuka. Status kedaluwarsa: buat invoice baru bila pengguna masih ingin bayar.# 1. buat invoice curl -H "X-API-Key: {api_key}" "https://{host}/api/v1/invoice?amount=50000" # 2. polling sampai lunas (aman diulang) curl -H "X-API-Key: {api_key}" "https://{host}/api/v1/invoice/status?invoice_id={invoice_id}"
GET /api/smm/services; catat id, rentang min/max, dan type-nya.POST /api/smm/order; kirim hanya parameter yang terdaftar untuk tipe itu.GET /api/smm/status/{order_id} sampai completed/partial. Bila refill: true, ajukan isi ulang setelah selesai.refund.GET /api/smm/orders dulu sebelum mengirim ulang. Jendela duplikat 90 detik akan menahan debit ganda, tapi memeriksa status lebih cepat daripada menunggu.GET /api/otp/countries), lalu ambil katalog di GET /api/otp/services: pilih product_id dari tiers untuk mengunci harga, atau GET /api/otp/operators bila ingin mengunci carrier.POST /api/otp/order sambil mengirim quoted_price (harga yang Anda tampilkan) supaya perubahan harga terdeteksi sebagai 409 price_changed, bukan kejutan debit.GET /api/otp/orders/{order_id} tiap 3-5 detik sampai status: received. SMS belum masuk sampai batas sewa, saldo dikembalikan otomatis.POST /api/otp/orders/{order_id}/finish. Ingin memakai nomor yang sama lagi? Pratinjau dulu dengan reactivate-options.# polling ringan: satu endpoint, semua kapabilitas di respons curl -H "X-API-Key: {api_key}" "https://{host}/api/otp/orders/{order_id}" -> bila "otp": "123456" dan status "received", pakai kode lalu finish
can_cancel, can_resend, can_finish) beserta *_available_at-nya, bukan perkiraan waktu di sisi klien, itulah aturan yang berlaku di sistem.| Tanggal | Perubahan yang terlihat oleh integrator |
|---|---|
| Okt 2026 | Kontrak OTP diselaraskan: kapabilitas server-authoritative (can_cancel, can_resend, can_replace, can_reactivate + *_available_at) hadir di respons API; endpoint finish, resend, reactivate-options, dan reactivate tersedia di jalur web dan API. |
| Okt 2026 | Batas laju diperketat: jaring global 600/menit/IP untuk seluruh rute, termasuk rute yang sebelumnya tanpa limiter. |
| Sep 2026 | Sistem SMM dimutakhirkan tanpa menukar status pesanan lama; refill, pengembalian proporsional, dan deteksi pesanan macet mengikuti kontrak baru. |
| Sep 2026 | Jendela duplikat 90 detik resmi berlaku untuk pesanan SMM, OTP, dan Premium, retry aman tanpa risiko debit ganda. |
| Sep 2026 | Minimum deposit QRIS turun menjadi Rp 100. |
Perubahan kontrak yang tidak kompatibel selalu diumumkan lewat halaman pengumuman di dalam aplikasi sebelum berlaku.