Dokumentasi
Satu script di browser, satu panggilan API dari server Anda. Semua yang Anda perlukan untuk go live, dalam satu halaman.
Quick start
Anda memerlukan public key (pk_...) untuk browser dan secret key (sk_...) untuk server. Keduanya ada di dashboard, di menu Situs dan key.
1. Tambahkan script
Pasang tag ini di halaman tempat pengguna mendaftar, login, mengklik offer, atau mengajukan cashout. Script menginisialisasi dirinya sendiri dari data-key
<script src="https://cashoutguard.com/v1/agent.js" data-key="pk_live_YOUR_PUBLIC_KEY" async></script>
2. Kumpulkan dan kirim request_id ke server Anda
Panggil collect() di momen yang penting, dengan nama event-nya. Hasilnya berupa { request_id, visitor_id }
const { request_id } = await CashoutGuard.collect({ event: 'cashout' });
collect() tidak pernah reject. Jika gagal (diblokir, offline, timeout), hasilnya request_id: null beserta string error. Tetap kirim form-nya dan biarkan server Anda yang memutuskan.
3. Minta keputusan dari server Anda
Kirim POST event ke /v1/evaluate dengan secret key Anda di header Authorization: Bearer sk_live_...
Jangan pernah menaruh secret key di kode browser atau aplikasi mobile. Hanya server Anda yang boleh memanggil /v1/evaluate.
Request evaluate
POST https://cashoutguard.com/v1/evaluate menilai satu event untuk satu akun, menghubungkannya dengan perangkat, jaringan, dan alamat payout-nya, lalu mengembalikan keputusan. Kirim dalam format JSON.
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
event | string | Wajib | signup, login, offer_click, conversion, cashout, atau custom. |
account_id | string | Wajib | ID pengguna Anda, maksimal 191 karakter. Gunakan ID acak, bukan email. |
request_id | string | Opsional | Dari collect() di browser. Berlaku 1 jam. Tanpa ini kami hanya punya data jaringan. |
ip | string | Opsional | IP pengguna. Hanya diperlukan jika Anda tidak punya request_id, misalnya untuk postback. |
email | string | Opsional | Disimpan sebagai hash. Mendeteksi domain email sekali pakai dan email yang dipakai bersama antar akun. |
payout_address | string | Opsional | Email PayPal, wallet, atau rekening tujuan uang. Disimpan sebagai hash. |
payout_method | string | Opsional | Teks bebas seperti paypal, usdt, atau giftcard. |
amount | number | Opsional | Jumlah cashout atau konversi. |
currency | string | Opsional | Kode mata uang, misalnya USD. Default USD untuk cashout. |
offer_id | string | Opsional | ID offer, untuk offer_click dan conversion. Dipakai untuk kecepatan offer. |
offer_country | string | Opsional | Negara yang dibayar offer (kode ISO, mis. US), pada konversi. Pengguna di negara lain ditandai. |
geo_country | string | Opsional | Geolokasi Anda sendiri untuk IP pengguna (kode ISO). Jika berbeda dengan milik kami, IP itu kemungkinan exit proxy. |
transaction_id | string | Opsional | ID transaksi konversi dari jaringan. Dipakai untuk menangkap duplikat. |
offer_name | string | Opsional | Judul penawaran seperti yang dilihat pengguna Anda. Ditampilkan di seluruh dasbor menggantikan id mentah. |
click_id | string | Opsional | Id klik Anda. Kirim nilai yang sama pada offer_click dan konversi agar keduanya terhubung. |
source | string | Opsional | Asal peristiwa, misalnya nama offerwall atau jaringan. |
meta | object | Opsional | Hingga 20 kolom teks tambahan yang disimpan bersama peristiwa (misalnya sub id). |
Response
Bentuk response selalu sama. Field yang tidak relevan bernilai null.
scorebernilai 0 sampai 100. Alasan-alasan digabungkan sehingga beberapa sinyal sedang bisa saling menambah tanpa melewati 100.reasonsberisi setiap sinyal yang terpicu, dari yang terkuat, beserta bobot, detail, dan label bahasa Inggris sederhana yang bisa langsung ditampilkan.device.confidencemenunjukkan seberapa unik perangkat tersebut. Fingerprint bisa dipalsukan, jadi kami tidak pernah mengklaim kepastian.linked_accountsberisi akun lain yang memakai perangkat, alamat payout, atau email yang sama dengan akun ini.cashouthanya diisi untuk event cashout dan menunjukkan statusnya di antrean review Anda.
Keputusan dan action
Bertindaklah berdasarkan field action, bukan decision. Ambang batas di bawah ini adalah default dan bisa diubah per situs di dashboard.
| Keputusan | Skor (default) | action di shadow | action di enforce | Yang harus dilakukan |
|---|---|---|---|---|
allow | 0-49 | allow | allow | Lanjutkan seperti biasa. |
review | 50-79 | allow | review | Tahan cashout atau minta verifikasi tambahan. Akan muncul di antrean review Anda. |
block | 80-100 | allow | block | Hentikan tindakannya. Bekukan saldo atau tolak pendaftaran. |
Dalam shadow mode, action selalu allow, jadi kode yang sama aman dirilis sebelum Anda menerapkan enforce. Saat beralih ke enforce, tidak ada yang berubah di kode Anda.
Jenis event
Kirim event yang Anda punya. Signup dan cashout paling penting; conversion menjadi dasar pengecekan kecepatan offer.
| Event | Kapan dikirim | Yang ditangkap |
|---|---|---|
signup | Akun dibuat | Multi-akun, bot, pendaftaran lewat VPN, email sekali pakai |
login | Login berhasil | Berbagi akun, perubahan negara, perangkat baru |
offer_click | Pengguna membuka offer | Mulai menghitung waktu untuk kecepatan offer |
conversion | Postback dari offerwall atau jaringan | Offer selesai terlalu cepat, transaksi duplikat, lonjakan konversi |
cashout | Pengguna mengajukan penarikan | Alamat payout yang dipakai bersama, velocity cashout, cashout dari akun baru |
custom | Apa pun yang ingin Anda nilai | Sinyal perangkat dan jaringan |
Offerwall dan postback
Konversi offerwall datang lewat postback, dari server ke server, tanpa browser. CashoutGuard menghubungkan setiap konversi ke klik yang memulainya, sehingga dinilai dengan perangkat dan jaringan klik tersebut.
1. Saat pengguna membuka penawaran
Kumpulkan di browser dan kirim offer_click dengan penawaran dan id klik Anda.
2. Saat postback tiba
Kirim conversion dari handler postback Anda dengan account_id dan click_id yang sama. Tidak perlu request_id. Sertakan IP pengguna jika offerwall memberikannya.
Konversi diperiksa untuk: selesai terlalu cepat untuk penawaran itu, konversi tanpa klik, klik dan konversi dari negara berbeda, pendapatan jauh di atas hari biasa akun, dan id transaksi ganda.
Jaringan offerwall
Jika Anda menjalankan jaringan dengan banyak publisher, kirim id akun yang menyertakan publisher dan aktifkan "Mode jaringan offerwall" di Situs. Akun hanya ditautkan dalam publisher yang sama, karena wajar jika satu orang memakai beberapa situs publisher Anda. Format: publisher_id:user_id
Katalog penawaran
POST /v1/offers mengirim nama penawaran Anda (hingga 1.000 per panggilan). Peristiwa lama dan baru akan menampilkan nama asli meskipun hanya membawa id.
Kode alasan
Kode-kode ini muncul di reasons[].code. Tampilkan teksnya ke moderator Anda; gunakan kodenya di logika Anda.
| Kode | Arti | Grup | Bobot |
|---|---|---|---|
ip_tor | Exit node Tor | Jaringan | 60 |
ip_vpn | Koneksi VPN | Jaringan | 45 |
ip_datacenter | IP datacenter / hosting | Jaringan | 40 |
timezone_mismatch | Zona waktu browser tidak cocok dengan lokasi IP | Jaringan | 20 |
webrtc_ip_leak | IP asli bocor dari negara lain | Jaringan | 30 |
ip_multi_timezone | IP yang sama dengan banyak zona waktu berbeda (proxy) | Jaringan | 50 |
proxy_farm_ip | Beberapa akun di satu IP, semuanya dengan jam negara lain yang sama (proxy bersama) | Jaringan | 60 |
provider_rotation | Banyak penyedia internet dalam beberapa hari, dengan jam negara lain (proxy residensial berputar) | Jaringan | 45 |
privacy_relay | iCloud Private Relay (fitur privasi) | Jaringan | 5 |
proxy_headers | Permintaan lewat proxy | Jaringan | 20 |
geo_sources_disagree | Sumber geolokasi tidak sama | Jaringan | 45 |
ip_shared_with_accounts | IP yang sama dipakai akun lain hari ini | Jaringan | 25 |
country_changed | Negara berubah | Jaringan | 15 |
impossible_travel | Perjalanan mustahil: IP dari dua negara berjauhan dalam beberapa jam | Jaringan | 50 |
locale_country_mismatch | Bahasa browser dari negara lain | Jaringan | 30 |
phone_country_mismatch | Telepon dari negara lain dari IP | Jaringan | 20 |
ip_flagged_on_network | IP diblokir di situs lain | Jaringan | 25 |
device_shared_with_accounts | Perangkat dipakai bersama akun lain | Perangkat | 55 |
automation_detected | Bot atau alat otomatisasi | Perangkat | 70 |
auto_clicker | Auto-clicker di ponsel | Perangkat | 55 |
scripted_behavior | Halaman dipakai oleh skrip | Perangkat | 45 |
emulator_or_vm | Emulator atau mesin virtual | Perangkat | 45 |
browser_tampering | Browser dimanipulasi / spoofing | Perangkat | 35 |
device_rooted | Ponsel di-root | Perangkat | 25 |
incognito | Mode penyamaran | Perangkat | 10 |
device_spoofed | Model ponsel palsu | Perangkat | 55 |
emulator_profile | Profil bawaan emulator | Perangkat | 60 |
cloud_phone | Ponsel cloud | Perangkat | 60 |
phone_farm_display | Layar peternakan ponsel | Perangkat | 45 |
device_market_mismatch | Ponsel khusus China di luar negeri | Perangkat | 25 |
storage_cleared_reappeared | Hapus cookie lalu kembali lagi | Perangkat | 15 |
no_device_data | Tidak ada data perangkat | Perangkat | 15 |
request_reused | Token perangkat dipakai ulang oleh akun lain | Perangkat | 40 |
device_farm_proxy | Peternakan ponsel lewat proxy residensial | Perangkat | 85 |
device_clones | Klon perangkat: satu ponsel yang mengatur ulang identitasnya agar tampak sebagai banyak akun baru di satu jaringan | Perangkat | 55 |
payout_address_shared | Alamat payout dipakai akun lain | Akun | 70 |
email_disposable | Email sekali pakai | Akun | 25 |
email_invalid | Alamat email yang tidak bisa menerima surat (domain email tidak ada) | Akun | 35 |
email_shared | Email sama dengan akun lain | Akun | 50 |
phone_shared | Nomor telepon dipakai akun lain | Akun | 50 |
phone_voip | Nomor VoIP atau virtual | Akun | 40 |
phone_invalid | Nomor telepon tidak valid | Akun | 30 |
many_devices_per_account | Terlalu banyak perangkat di satu akun | Akun | 20 |
flagged_on_network | Ditandai di situs lain yang dilindungi CashoutGuard | Akun | 45 |
face_same_person | Wajah sama dengan akun lain | Akun | 0 |
offer_completed_too_fast | Offer selesai terlalu cepat, tidak masuk akal | Perilaku | 40 |
slow_after_click | Konversi lama setelah klik | Perilaku | 0 |
conversion_velocity | Terlalu banyak konversi per jam | Perilaku | 30 |
conversion_without_click | Konversi tanpa klik dari wall Anda | Perilaku | 35 |
click_conversion_country_mismatch | Klik di satu negara, konversi di negara lain | Perilaku | 30 |
offer_country_mismatch | Negara offer berbeda dari pengguna | Perilaku | 45 |
click_velocity | Terlalu banyak klik offer dalam beberapa menit | Perilaku | 35 |
earnings_spike | Pendapatan jauh di atas pengguna normal | Perilaku | 30 |
source_high_reversals | Sumber dengan banyak chargeback | Perilaku | 45 |
offer_high_reversals | Penawaran dengan banyak chargeback | Perilaku | 35 |
duplicate_transaction | ID transaksi duplikat | Perilaku | 60 |
offer_repeated_other_publisher | Penawaran yang sama sudah dikerjakan lewat publisher lain | Perilaku | 85 |
offer_repeated_other_account | Penawaran yang sama sudah dikerjakan akun lain di perangkat ini | Perilaku | 85 |
offer_farm_burst | Gelombang farm: banyak akun baru dengan perangkat farm di penawaran ini dalam beberapa jam | Perilaku | 30 |
signup_burst | Lonjakan pendaftaran: beberapa akun mendaftar dalam hitungan detik dari IP berbeda | Perilaku | 25 |
face_check_required | Pemeriksaan wajah diperlukan, belum dilakukan | Perilaku | 0 |
face_check_failed | Pemeriksaan wajah gagal | Perilaku | 0 |
publisher_farm_wave | Gelombang farm dari publisher-nya: sebagian besar akun baru yang dikirim ke penawaran ini berasal dari cloud phone atau emulator | Perilaku | 55 |
cashout_velocity | Terlalu banyak cashout per hari | Perilaku | 30 |
new_account_cashout | Cashout dari akun yang baru dibuat | Perilaku | 20 |
blocklisted | Ada di blocklist Anda | Daftar Anda | 100 |
Bobot digabungkan dengan noisy-OR: score = 100 x (1 - hasil kali (1 - weight/100)). Dua sinyal bernilai 40 menghasilkan 64, bukan 80. Kecocokan dengan blocklist selalu menghasilkan 100.
Webhook
Atur URL webhook di dasbor. Kami mengirim POST untuk setiap peristiwa yang dinilai block (event.blocked), saat akun berubah menjadi block (account.blocked), dan saat tim Anda memutuskan penarikan (cashout.decided). Abaikan tipe yang tidak Anda pakai.
Setiap request ditandatangani dengan webhook secret Anda. HMAC-SHA256 (hex) dari raw body ada di header X-CashoutGuard-Signature
Balas dengan status 2xx apa pun. Pengiriman yang gagal akan dicoba ulang hingga 5 kali: setelah 10 detik, 1 menit, 5 menit, dan 15 menit.
Status akun
GET /v1/accounts/{account_id} mengembalikan gambaran risiko terkini sebuah akun tanpa membuat event.
POST /v1/accounts/{account_id}/status memungkinkan alat moderasi Anda sendiri mengubah status akun.
active: Penilaian normal.allowlisted: Skor dibatasi di bawah ambang review. Untuk pengguna tepercaya dan staf.blocked: Setiap event mengembalikan block dengan skor 100.
Pembatalan & akurasi
POST /v1/outcomes melaporkan apa yang terjadi pada konversi setelah kami beri skor: dibatalkan offerwall atau pengiklan (chargeback) atau dikonfirmasi valid. Kami mencocokkan id Anda dan mengukur mesin pada trafik Anda di halaman Akurasi.
Tanpa kode: unggah ekspor pembatalan bulanan dari offerwall Anda (CSV atau Excel) di halaman Akurasi. Kolom id kami temukan otomatis.
PHP, Node.js, Python, Android
Tidak perlu SDK. Panggilan HTTP biasa dengan timeout singkat sudah cukup. Contoh lengkap untuk cashout:
- cashoutguard.php: PHP 7.4+, satu file, tanpa Composer. Cukup require.
- composer require cashoutguard/cashoutguard-php: klien PHP yang sama dengan README, untuk folder vendor Anda.
- npm install @cashoutguard/node: Node 18+, termasuk tipe TypeScript.
- cashoutguard-wordpress.zip: plugin WordPress: skrip browser di setiap halaman, pendaftaran dan login dinilai, serta hook untuk penarikan, konversi offerwall, dan pembatalan.
Error dan batasan
| HTTP | Body | Arti |
|---|---|---|
| 401 | missing_or_invalid_secret_key | Secret key tidak ada, salah, atau sudah dicabut. Respons menyebut alasannya di "reason" (missing, public_key, unknown_secret, placeholder, malformed) dan cara memperbaikinya di "hint". |
| 404 | not_found | Akun tidak ditemukan (endpoint akun). |
| 422 | { "message", "errors" } | Body tidak valid. errors mencantumkan setiap field. |
| 429 | Too Many Requests | Batas rate tercapai. API server mengizinkan 3.000 request per menit per situs. |
| 401 · agent.js | unknown_public_key | data-key bukan kunci publik situs mana pun. Salin lagi pk_live_... dari Instalasi. |
| 403 · agent.js | origin_not_allowed | Domain halaman tidak ada di origin yang diizinkan untuk situs. Tambahkan di Situs atau kosongkan daftarnya. localhost selalu bisa. agent.js juga menjelaskannya di konsol browser. WebView aplikasi mengirim origin "null": tambahkan null ke daftar untuk menerimanya. SDK Android native tidak memerlukan apa pun. |
| 403 | account_suspended | Akun ditangguhkan, biasanya karena tagihan belum dibayar. Periksa Penagihan. |
| 503 | temporarily_unavailable | Gangguan singkat di pihak kami. Izinkan aksinya dan coba lagi nanti. |
Fail open: jika panggilan timeout atau error, izinkan tindakannya dan catat di log. Jangan biarkan gangguan di pihak kami menghentikan pengguna Anda.