Cara Menerbitkan Kunci API CAPTCHA untuk Pelanggan Anda

Kalau Anda menjalankan CapSkip untuk orang lain, kunci API CAPTCHA bisa Anda terbitkan begitu seorang pelanggan membayar, langsung dari webhook penagihan Anda. Remote Key Management membuka endpoint POST yang menambah, menampilkan, menghapus, membatasi, dan mengukur kunci pada instance yang sedang berjalan, dan kunci baru sudah aktif pada permintaan pemecahan berikutnya. Tanpa restart, tanpa langkah manual, dan tidak ada lagi yang menghalangi antara pembayaran yang lolos dan pelanggan yang mulai memecahkan CAPTCHA. Setiap kunci juga bisa membawa batas kreditnya sendiri per jenis CAPTCHA, sehingga tingkat paket berubah menjadi angka yang ditegakkan sendiri oleh pemecahnya, bukan aturan yang harus diawasi sistem penagihan Anda. Tulisan ini membahas cara menerbitkan kunci saat berlangganan, menetapkan dan menambah batas itu, mengukur pemakaian tiap pelanggan, mencabutnya saat berhenti, dan satu kesalahan jaringan yang justru dipermudah oleh susunan ini.
Apa yang Anda butuhkan
- CapSkip berjalan di sebuah mesin Windows yang Anda kendalikan. Mesin itulah layanan pemecahan Anda, dan hanya mesin itu yang perlu memasang aplikasinya. Pelanggan Anda tidak memasang apa pun.
- Mode Server, supaya pelanggan itu benar-benar bisa menjangkaunya. Mode Local mendengarkan di alamat loopback dan hanya melayani perangkat itu sendiri, sedangkan mode Server mendengarkan di IP jaringan atau IP publik Anda sehingga mesin lain bisa terhubung. Keduanya dijelaskan di pengaturan koneksi, dan IP publik statis sebaiknya sudah ada sebelum Anda memberikan alamatnya kepada siapa pun.
- Satu kali kunjungan ke jendela CapSkip untuk membuat token admin. Hanya langkah inilah yang terjadi di antarmuka, dan Anda tidak pernah mengulanginya.
- Suatu tempat untuk menjalankan pemanggilannya: handler webhook penagihan Anda, backend dasbor Anda, atau sebuah terminal selama Anda masih menguji.
Satu hal perlu dinyatakan terus terang sebelum masuk ke kode, karena justru bagian inilah yang membuat model ini masuk akal. Kunci yang Anda bagikan adalah kunci yang Anda cetak sendiri. Ini bukan kredit yang Anda beli dari vendor lalu Anda jual kembali, dan mencetak satu kunci sama sekali tidak berbiaya. CapSkip berjalan di perangkat keras Anda, jadi seratus kunci pelanggan berbiaya sama persis dengan satu kunci.
Yang kini bisa dibawa sebuah kunci adalah batas kreditnya sendiri, ditetapkan terpisah untuk tiap jenis CAPTCHA. Itu mengubahnya dari sekadar label menjadi tingkat paket yang ditegakkan sendiri oleh pemecahnya: "Starter, 10.000 pemecahan reCAPTCHA" berubah menjadi angka yang dihitung mundur oleh CapSkip, bukan sesuatu yang harus Anda awasi. Ada delapan keranjang penagihan, dan pembagiannya sengaja dibuat lebih kasar daripada jenis tugas milik pemecahnya:
- Keranjang ImageToText mencakup pemecahan gambar dan OCR.
- Keranjang Recaptcha mencakup v2, v3, dan kedua varian Enterprise sekaligus.
- Keranjang Turnstile mencakup Cloudflare Turnstile.
- Keranjang GeeTest mencakup GeeTest.
- Keranjang Altcha mencakup ALTCHA.
- Keranjang CaptchaFox mencakup CaptchaFox.
- Keranjang Capy mencakup Capy Puzzle.
- Keranjang FriendlyCaptcha mencakup Friendly Captcha.
Keranjang tanpa batas yang ditetapkan berarti tanpa batas, dan begitulah perilaku setiap kunci sebelum fitur ini ada. Jadi memperbarui CapSkip dengan sendirinya tidak mengubah apa pun: setiap kunci yang sudah Anda terbitkan tetap tanpa batas di kedelapan keranjang sampai Anda menetapkan batasnya, dan pemanggilan tambah yang tidak menyebut batas apa pun tetap membuat kunci tanpa batas.
Langkah 1: aktifkan Remote Key Management
Sakelarnya ada di Settings, di bawah API access, lalu Remote Key Management. Aktifkan lalu tekan tombol Generate.
Token hanya ditampilkan satu kali dan disimpan sebagai hash bergaram saja, jadi tidak ada tempat untuk membacanya kembali nanti. Kalau hilang, buat yang baru, dan yang lama langsung tidak berlaku. Untuk mematikan API admin tanpa menerbitkan token baru, tekan tombol Revoke, yang menghapus token yang tersimpan. Simpan di tempat yang sama dengan rahasia lain milik sistem penagihan Anda, bukan di dalam kode aplikasi.
Endpoint ini berada di host dan port yang sama dengan yang sudah menjawab permintaan pemecahan Anda. Kalau pelanggan Anda berbicara ke port 8080, di situ pula API admin berada. Itu praktis, dan itu pula yang harus Anda waspadai: ada bagian tersendiri soal ini di bawah.
Selama fitur ini mati, setiap jalur admin mengembalikan 404 polos tanpa body. Jalur yang tidak dikenal mendapat jawaban yang persis sama, dan itu disengaja: orang yang menyisir port tidak bisa membedakan instance yang fiturnya dimatikan dari instance yang bahkan tidak mengenal fitur ini.
Langkah 2: terbitkan kunci saat pelanggan berlangganan
Setiap endpoint memakai POST, menerima body JSON, dan mensyaratkan header Authorization yang membawa token sebagai kredensial Bearer. Pemanggilan tambah membutuhkan sebuah nama. Kirim namanya saja dan biarkan CapSkip yang membuat nilai kuncinya, dan di sini itulah yang Anda mau: pelanggan tidak seharusnya memilih kredensialnya sendiri. Sertakan objek grants, dan kunci itu lahir dengan batas paket pelanggan tersebut sudah terpasang.
# No install needed. Name the key after the customer, not after the plan.
curl -X POST http://YOUR_SERVER:8080/admin/keys/add \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"cust_10482","grants":{"Recaptcha":10000,"ImageToText":50000}}'{
"errorId": 0,
"key": {
"name": "cust_10482",
"key": "a1b2c3d4e5f6...",
"grants": {
"ImageToText": 50000,
"Recaptcha": 10000,
"Turnstile": null,
"GeeTest": null, "Altcha": null, "CaptchaFox": null, "Capy": null, "FriendlyCaptcha": null
}
}
}Responsnya melaporkan kedelapan keranjang, bukan hanya dua yang Anda tetapkan, jadi Anda tidak pernah perlu membaca ulang untuk memastikan apa yang baru Anda buat. Beri nama kunci berdasarkan sesuatu yang stabil di sistem Anda sendiri, misalnya id pelanggan atau id langganan. Nama bersifat unik dan aturan itu ditegakkan saat penambahan, sehingga nama menjadi pegangan yang andal untuk setiap operasi berikutnya. Menamai kunci berdasarkan paket atau tanggal justru kesalahan yang membuat hari pembatalan jadi menyakitkan.
Ada empat aturan yang mengatur objek grants, dan yang benar-benar menyelamatkan Anda adalah yang terakhir:
- Jangan kirim sama sekali, dan kunci itu tanpa batas di mana pun. Ini perilaku yang sudah ada sebelumnya, jadi integrasi yang ditulis sebelum kuota ada tetap berjalan tanpa disentuh.
- Lewatkan satu keranjang, atau kirim sebagai JSON null, dan keranjang itu tanpa batas. Kirim angka nol dan keranjang itu justru dimulai dalam keadaan habis.
- Nama keranjang tidak membedakan huruf besar kecil, tetapi credits harus berupa bilangan bulat JSON nol atau lebih tanpa tanda kutip, bukan string dalam tanda kutip dan bukan bilangan desimal.
- Seluruh permintaan divalidasi lebih dulu, dan baru setelah itu kuncinya dibuat. Nama keranjang yang tidak dikenal atau angka yang salah mengembalikan 400 dan tidak membuat apa pun, jadi permintaan yang ditolak tidak mungkin meninggalkan kunci yang batasnya setengah jadi.
Tetapkan batasnya saat pembuatan, bukan membuat kuncinya dulu lalu membatasinya belakangan. Cara kedua menyisakan jeda, sesingkat apa pun, ketika sebuah kunci pelanggan yang benar-benar baru sudah aktif tanpa batas sama sekali.
Aturan keunikan itu sekaligus menjadi pengaman idempotensi Anda. Penyedia pembayaran mengirim ulang webhook, dan peristiwa langganan yang terkirim ulang akan kembali sebagai 409 dengan ERROR_KEY_EXISTS, bukan diam-diam membuat kunci kedua untuk pelanggan yang sama. Perlakukan 409 itu sebagai keberhasilan di handler Anda, dan masalah pengiriman ulang pun selesai.
Nilainya kembali tepat satu kali, di dalam respons itu. Tampilkan ke pelanggan atau simpan di tempat yang dibaca dasbor Anda, sebab menampilkan daftar kunci belakangan adalah operasi admin dan bukan sesuatu yang ingin Anda jalankan hanya untuk memulihkan kredensial satu pelanggan.
Langkah 3: sesuaikan batas saat upgrade atau perpanjangan
Endpoint grant menuliskan batas satu keranjang pada satu kunci. Pilih kuncinya berdasarkan nama atau berdasarkan nilai, tepat salah satu dari keduanya, sama seperti pada penghapusan.
# Upgrade: replace the limit outright.
curl -X POST http://YOUR_SERVER:8080/admin/keys/grant \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"cust_10482","bucket":"Recaptcha","credits":25000,"mode":"set"}'
# Top-up: add to whatever is left.
# -d '{"name":"cust_10482","bucket":"Recaptcha","credits":10000,"mode":"add"}'Kedua mode itu tidak simetris. Mode set mengganti angkanya secara langsung, dan nilai credits berupa JSON null atau yang tidak dikirim sama sekali dalam mode set akan mengembalikan batasnya menjadi tanpa batas. Itulah satu-satunya cara menghapus batas setelah batas itu ada. Perlu diperhatikan bahwa nilai credits nol berarti kebalikan dari null: ia menghabiskan keranjangnya, bukan menghapus batasnya. Mode add menghitung nilai yang ada ditambah angka Anda, memperlakukan tanpa batas sebagai nol, sehingga ia justru membuat batas pada keranjang yang tadinya tidak punya. Mode ini menuntut nilai credits di atas nol.
Tiga bentuk permintaan ditolak mentah-mentah alih-alih dijalankan, masing-masing karena kegagalannya akan berlangsung tanpa terlihat:
- Menambahkan nol. Skrip penambahan kredit yang berjalan tiap malam dan menghitung target dikurangi nilai sekarang akan menghasilkan nol untuk setiap pelanggan yang sudah mencapai target. Terhadap keranjang tanpa batas, itu justru menetapkan batas tepat nol dan menghentikan kunci itu memecahkan CAPTCHA, jadi gunakan mode set ketika yang Anda maksud memang nol.
- Angka negatif, di mode mana pun. Menambahkan minus 500 terbaca sebagai pengurangan pada keranjang yang dibatasi, tetapi permintaan yang sama persis terhadap keranjang tanpa batas akan mentok di nol dan diam-diam mengubahnya menjadi keranjang yang habis. Pemanggilnya tidak bisa menebak mana yang akan ia dapat hanya dari permintaannya sendiri, jadi keduanya tidak diizinkan.
- Angka dalam tanda kutip. Mengirim nilai credits sebagai string dalam tanda kutip berarti "batasi kunci ini pada angka tersebut", tetapi bila diperlakukan sebagai nilai yang hilang artinya justru sebaliknya, yaitu menghapus batasnya, dan tetap mengembalikan keberhasilan. Memberi tanda kutip pada angka persis seperti yang tanpa sengaja dilakukan sebuah skrip shell, jadi kirim credits tanpa tanda kutip.
Satu hal perlu direncanakan sejak awal: sebuah grant adalah saldo kredit, bukan jatah bulanan. Tidak ada apa pun di dalam CapSkip yang berjalan mengikuti kalender. Untuk paket bulanan berbasis pemakaian, panggil endpoint grant dalam mode set dengan jatah paket pada awal setiap siklus penagihan, dari webhook perpanjangan Anda. Untuk paket yang kredit tak terpakainya bergulir, gunakan mode add dengan jatah siklus tersebut.
Langkah 4: ukur pemakaian tiap pelanggan
Endpoint usage menerima objek kosong dan mengembalikan konsumsi per kunci dan per keranjang untuk semua kunci sekaligus.
# Every key, every bucket, in one call.
curl -X POST http://YOUR_SERVER:8080/admin/keys/usage \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{}'{
"errorId": 0,
"keys": [
{
"name": "cust_10482",
"key": "a1b2c3d4e5f6...",
"buckets": [
{
"bucket": "Recaptcha",
"granted": 10000,
"remaining": 9581,
"used": 419,
"failed": 12,
"inFlight": 3,
"lastUsed": "2026-08-26T09:14:02.1234567Z"
}
]
}
]
}| Kolom | Arti |
|---|---|
| "granted" | Batasnya, atau null bila tanpa batas. |
| "remaining" | Sisa kredit, atau null ketika keranjangnya tanpa batas. |
| "used" | Pemecahan yang berhasil. Hanya inilah yang menghabiskan kredit. |
| "failed" | Percobaan yang gagal: dihitung untuk keperluan diagnosis, tetapi tidak pernah ditagihkan. |
| "inFlight" | Tugas yang sedang dipesan saat ini. Sudah dikurangkan dari sisa kredit, dan dikembalikan kalau tugasnya gagal. |
| "lastUsed" | Waktu ISO-8601 UTC dari pemecahan berhasil terakhir, atau null kalau kunci itu belum pernah dipakai. |
Penghitungnya bersifat kumulatif sepanjang umur kunci dan bertahan melewati restart. Karena satu pemanggilan mengembalikan semua kunci, jalankan secara terjadwal untuk memasok dasbor Anda, bukan memanggilnya satu per satu per pelanggan. Field lastUsed juga cara Anda menemukan kunci menganggur yang layak ditarik kembali.
Langkah 5: cabut kuncinya saat mereka berhenti
Penghapusan menerima tepat satu penanda, entah nilai kuncinya atau namanya. Karena Anda menamai kunci menurut pelanggan, namanya itulah yang dipakai:
# By name, which is unambiguous because names are unique.
curl -X POST http://YOUR_SERVER:8080/admin/keys/delete \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{"name":"cust_10482"}'
# By value works too, if that is what your records hold:
# -d '{"key":"the-old-value"}'Pencabutan berlaku pada permintaan pemecahan berikutnya, jadi akses berakhir tepat saat pemanggilan itu selesai. Sejak saat itu pemanggilan pelanggan tersebut gagal dengan ERROR_KEY_DOES_NOT_EXIST, dan itu sinyal yang cukup jelas: integrasi mereka bisa menampilkannya sebagai langganan yang habis masa berlakunya, bukan sebagai gangguan.
Tentukan dengan sadar kapan ini dijalankan. Menghapus pada peristiwa pembatalan memutus akses seketika, padahal pelanggan biasanya sudah membayar sampai akhir periode. Menghapus pada peristiwa akhir periode itulah yang sebenarnya diinginkan kebanyakan orang. Pembayaran gagal adalah kasus ketiga: memberi tenggang singkat sebelum pencabutan menimbulkan jauh lebih sedikit tiket dukungan daripada kunci yang lenyap saat kartu dicoba tagih ulang.
Langkah 6: cocokkan daftarnya dengan sistem penagihan Anda
Pemanggilan daftar cukup dengan objek kosong dan mengembalikan setiap kunci yang saat ini diterima instance.
# The audit: exactly who can solve right now.
curl -X POST http://YOUR_SERVER:8080/admin/keys/list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{}'{
"errorId": 0,
"keys": [
{ "name": "cust_10482", "key": "..." },
{ "name": "cust_10515", "key": "..." }
]
}errorId bernilai 0 berarti berhasil, konvensi yang sama dipakai endpoint pemecahan. Jalankan ini secara terjadwal dan bandingkan namanya dengan langganan aktif Anda. Kunci tanpa langganan yang cocok berarti ada orang yang masih memecahkan CAPTCHA secara gratis, dan langganan tanpa kunci berarti pelanggan yang webhook penerbitannya hilang dan yang kemungkinan besar sebentar lagi membuka tiket. Keduanya diam sampai Anda memeriksanya, dan pemanggilan inilah satu-satunya tempat kebenarannya berada.
Apa yang dilihat pelanggan Anda ketika batasnya tercapai
Kunci yang tidak lagi punya sisa kredit di sebuah keranjang akan menerima ERROR_ZERO_BALANCE dari endpoint pemecahan, dan itu hanya untuk tugas di keranjang tersebut. Keranjang lain pada kunci yang sama tetap bekerja. Kesalahan itu datang dari API pemecahan, bukan dari API admin ini, dan bentuknya sama persis di semua lapisan emulasi: 2captcha, Anti-Captcha, CapSolver, dan DeathByCaptcha. Jadi penanganan yang sudah dimiliki pelanggan untuk saldo 2captcha yang habis sudah mencakup kasus ini tanpa perubahan apa pun di sisi mereka.
Pemeriksaan saldo pun berperilaku masuk akal. Pelanggan yang memanggil getBalance, atau aksi saldo pada res.php, melihat sisa kredit mereka yang sebenarnya, dijumlahkan dari semua keranjang yang dibatasi, sehingga angkanya menurun seiring pemakaian. Kunci yang tidak punya batas di mana pun tetap melaporkan nilai penanda lama 999999.99, yang berarti klien yang memeriksa kewajaran saldo sebelum mengirim tetap bekerja persis seperti sebelumnya.
Ada satu titik buta yang perlu diketahui. Format pengirimannya hanya menyediakan ruang untuk satu angka, jadi kunci dengan 50.000 kredit gambar dan nol kredit reCAPTCHA tetap melaporkan saldo yang tampak sehat. Apa pun yang membutuhkan rincian per jenis harus membaca endpoint usage sebagai gantinya, dan endpoint itu hanya untuk admin.
Menyambungkannya ke webhook langganan
Digabungkan, seluruh integrasinya hanyalah satu tabel paket dan empat handler:
# pip install requests
import requests
BASE = "http://YOUR_SERVER:8080"
AUTH = {"Authorization": "Bearer YOUR_TOKEN"}
BUCKETS = ("ImageToText", "Recaptcha", "Turnstile", "GeeTest", "Altcha", "CaptchaFox", "Capy", "FriendlyCaptcha")
# None means unlimited; an omitted bucket is unlimited too.
PLANS = {
"starter": {"ImageToText": 50_000, "Recaptcha": 10_000},
"pro": {"ImageToText": 500_000, "Recaptcha": 100_000,
"Turnstile": 25_000},
"unlimited": {},
}
def admin(path, body):
r = requests.post(f"{BASE}/admin/keys/{path}", json=body,
headers=AUTH, timeout=10)
if r.status_code == 409:
return None # already exists: a retried webhook
r.raise_for_status()
return r.json()
def on_subscription_active(customer_id, plan):
body = {"name": f"cust_{customer_id}"}
if PLANS[plan]:
body["grants"] = PLANS[plan]
created = admin("add", body)
return created["key"]["key"] if created else None
def apply_plan(customer_id, plan):
"""Upgrade, downgrade, or start-of-cycle reset."""
limits = PLANS[plan]
for bucket in BUCKETS:
admin("grant", {"name": f"cust_{customer_id}", "bucket": bucket,
"mode": "set", "credits": limits.get(bucket)})
def on_subscription_ended(customer_id):
admin("delete", {"name": f"cust_{customer_id}"})
def usage_report():
return admin("usage", {})["keys"]Perhatikan bahwa apply_plan menulis ke setiap keranjang, bukan hanya menambal yang berubah saja. Itu disengaja: saat turun paket, ia membersihkan batas yang dimiliki paket lama tetapi tidak dimiliki paket baru, sebab nilai credits yang hilang dalam mode set berarti tanpa batas. Untuk paket bergulir, alihkan ke mode add dan lewati keranjang yang batasnya None, karena mode add menolak nilai yang hilang atau nol.
Tangani None dari langganan yang terkirim ulang dengan sadar. Artinya kuncinya ada tetapi nilainya tidak bisa Anda lihat lagi, jadi kalau Anda gagal menyimpannya pada kali pertama, pemulihannya adalah menghapus lalu menambahkan ulang, bukan menampilkan daftar. Menyimpan nilainya begitu pertama kali Anda terima membuat situasi ini tidak pernah muncul.
Jangan biarkan API admin berada di port yang menghadap pelanggan
Untuk susunan seperti ini, bagian inilah yang paling penting, karena kepraktisan satu host dan satu port berlaku dua arah. Pelanggan Anda memang perlu menjangkau endpoint pemecahan. Endpoint admin berada di port yang sama, hanya dilindungi Bearer token, dan tidak ada pemeriksaan lapisan transport, jadi di port khusus token itu melintas sebagai HTTP teks terbuka. Siapa pun yang bisa mengamati lalu lintas itu bisa membacanya, dan siapa pun yang memegangnya bisa menerbitkan kunci untuk dirinya sendiri.
Pasang reverse proxy di depan instance lalu pisahkan dua kelompok penggunanya:
- Terbitkan ke internet hanya jalur pemecahan, lewat HTTPS yang diakhiri di proxy, dan kembalikan 404 untuk apa pun di bawah jalur admin.
- Jangkau endpoint admin dari backend Anda sendiri lewat rute privat: alamat loopback kalau layanan penagihan Anda berjalan di mesin Windows yang sama, selebihnya lewat jaringan privat, VPN, atau terowongan SSH.
Patokannya begini: token admin tidak boleh keluar dari infrastruktur Anda, dan port yang diajaknya bicara tidak boleh port yang bisa dijangkau pelanggan. Jangan pernah membuka jalur admin ke internet terbuka, baik fiturnya aktif maupun tidak.
Ada satu batasan lagi yang perlu diketahui, sebab dasbor pelanggan justru hal paling jelas yang ingin dibangun di sini. Browser tidak bisa memanggil endpoint ini, karena respons admin sengaja tidak membawa header CORS sama sekali. Dasbor Anda harus melewati backend Anda sendiri, dan di situlah memang tempat token seharusnya berada.
Ke mana kunci sebenarnya ditulis
Kunci masuk ke tempat kunci Anda memang sudah tersimpan. Direct Input dan From File adalah dua daftar yang terpisah, dan API membaca serta menulis ke daftar mana pun yang sedang dipilih. Mengganti sumbernya di jendela pengaturan juga mengubah apa yang dilihat endpoint, jadi pastikan dulu Anda sedang di mode yang mana sebelum bingung kenapa kunci yang baru saja diterbitkan tidak ada di daftar.
Mode file punya satu perilaku yang sebaiknya Anda ketahui lebih dulu: penulisan pertama akan menulis ulang berkas kunci teks biasa menjadi JSON. Tidak ada yang hilang, tetapi formatnya berubah permanen, jadi cadangkan dulu berkasnya kalau ada hal lain yang ikut membacanya. Kalau tidak ada berkas yang dipilih sama sekali, penulisan tidak punya tempat mendarat dan Anda akan mendapat ERROR_ADMIN_STORE_FAILURE dengan kode 500. Hampir selalu, 500 di sini berarti itu.
Daftar yang dibuat sebelum fitur ini ada masih mungkin memuat nama ganda, karena keunikan hanya ditegakkan saat penambahan. Menghapus berdasarkan nama pada kasus seperti itu mengembalikan ERROR_KEY_NAME_AMBIGUOUS dan tidak mengubah apa pun. Hapus berdasarkan nilainya saja, ambiguitasnya langsung hilang.
Tanda kutip di shell Windows, kalau Anda menguji dari mesin itu sendiri
CapSkip adalah aplikasi Windows, jadi mesin tempat Anda menguji pun sering kali Windows. Command Prompt tidak memperlakukan kutip tunggal sebagai tanda kutip. Perintah yang Anda salin mengirim tanda kutip itu sebagai bagian dari body JSON, parser menolaknya, dan Anda mendapat ERROR_ADMIN_BAD_REQUEST pada perintah yang tampak sepenuhnya benar.
| Shell | Body kosong | Dengan field |
|---|---|---|
| Command Prompt | -d "{}" | -d "{\"name\":\"prod\"}" |
| PowerShell, memakai curl.exe | -d '{}' | -d '{\"name\":\"prod\"}' |
| Git Bash, macOS, Linux | -d '{}' | -d '{"name":"prod"}' |
Di PowerShell, panggil curl.exe dengan nama lengkapnya. curl polos di sana adalah alias untuk Invoke-WebRequest, yang menerima argumen yang sama sekali berbeda dan akan gagal dengan cara yang tidak ada hubungannya dengan API ini.
Kode kesalahan
| Status | Kode | Penyebab |
|---|---|---|
| 404 | teks biasa | Fitur mati, atau jalur tidak dikenal. Sengaja dibuat tidak bisa dibedakan. |
| 401 | ERROR_ADMIN_UNAUTHORIZED | Token tidak ada, rusak, atau salah. |
| 405 | ERROR_ADMIN_METHOD_NOT_ALLOWED | Anda mengirim sesuatu selain POST. |
| 400 | ERROR_ADMIN_BAD_REQUEST | Body yang salah bentuk: penambahan tanpa nama, penghapusan dengan kedua penanda atau tanpa satu pun, nama keranjang yang tidak dikenal, nilai credits atau grants yang bukan bilangan bulat non-negatif tanpa tanda kutip, atau grant dalam mode add tanpa nilai credits di atas nol. Tidak ada yang dibuat dan tidak ada yang diubah. |
| 409 | ERROR_KEY_EXISTS | Nama atau nilai itu sudah dipakai. Pada handler langganan, ini biasanya webhook yang terkirim ulang. |
| 409 | ERROR_KEY_NAME_AMBIGUOUS | Penghapusan atau grant berdasarkan nama cocok dengan beberapa kunci. Pilih berdasarkan nilai kuncinya saja. |
| 404 | ERROR_KEY_NOT_FOUND | Penghapusan atau grant tidak cocok dengan apa pun. Biasanya pembatalan yang sudah diproses sebelumnya. |
| 500 | ERROR_ADMIN_STORE_FAILURE | Gagal menyimpan. Biasanya mode file tanpa berkas yang dipilih. |
Satu kode lagi layak disebut di sini meskipun datangnya dari sisi lain produk. ERROR_ZERO_BALANCE dikembalikan oleh endpoint pemecahan, bukan API admin ini, dan muncul ketika kredit sebuah kunci habis di keranjang tempat tugas itu berada. Kalau pelanggan melaporkannya, jawabannya adalah menambah kredit, bukan sesuatu yang rusak pada penerbitan kunci.
Kode-kode ini mendampingi kode kesalahan pemecahan, bukan menggantikannya, dan daftar lengkapnya ada di Dokumentasi API CapSkip.
FAQ
Seberapa cepat kunci baru benar-benar mulai bekerja?
Pada permintaan pemecahan berikutnya. Tidak ada yang di-cache dan tidak ada yang perlu dimuat ulang, jadi pelanggan yang menerima kuncinya dari halaman checkout Anda bisa memakainya pada menit yang sama. Pencabutan sama seketikanya ke arah sebaliknya, dan karena itulah waktu penjalanan handler pembatalan Anda adalah keputusan kebijakan, bukan keputusan teknis.
Apakah setiap kunci pelanggan tambahan menimbulkan biaya?
Tetap nol. Mencetak kunci itu gratis dan tidak ada meteran vendor di belakangnya. Yang berubah adalah kunci kini bisa membawa batas kredit milik Anda sendiri, sehingga ia dapat mewakili sebuah tingkat paket: pembukuannya milik Anda, dan penetapan harganya juga. SDK pemecahan CAPTCHA membaca kunci mana pun yang Anda berikan, jadi cara membaginya sepenuhnya Anda yang merancang.
Bisakah saya membatasi laju permintaan seorang pelanggan lewat API ini?
Tidak, dan batas kredit bukan penggantinya. Kuota itu anggaran, bukan plafon permintaan per detik: ia membatasi berapa banyak yang didapat pelanggan secara total, bukan seberapa keras ia boleh menghantam endpoint dalam satu detik tertentu. Pembatasan laju tetap menjadi urusan reverse proxy yang memang sudah Anda pasang di depan instance, berdasarkan kunci API yang dikirim pelanggan.
Apakah batas kredit disetel ulang setiap bulan?
Tidak. Sebuah grant adalah saldo yang terus menurun sampai Anda mengubahnya, dan tidak ada apa pun di dalam CapSkip yang berjalan mengikuti kalender. Panggil endpoint grant dalam mode set pada awal setiap siklus penagihan untuk mengembalikannya ke jatah paket, atau dalam mode add kalau kredit yang tak terpakai seharusnya bergulir.
Apakah pemecahan yang gagal memakan kredit pelanggan?
Tidak. Kredit hanya terpakai pada pemecahan yang berhasil. Kegagalan dihitung terpisah di laporan pemakaian sehingga Anda tetap bisa melihatnya, dan tugas yang gagal saat sedang berjalan akan mengembalikan pesanannya. Artinya, pelanggan yang sedang ditantang habis-habisan oleh situs sulit tidak diam-diam menghanguskan jatahnya pada percobaan yang tidak menghasilkan apa-apa.
Apa yang terjadi pada kunci saya yang sudah ada ketika saya memperbarui CapSkip?
Tidak terjadi apa-apa. Setiap kunci yang sudah Anda terbitkan tanpa batas di kedelapan keranjang sampai Anda menetapkan batas padanya, dan pemanggilan tambah yang tidak menyebut grants tetap membuat kunci tanpa batas persis seperti dulu. Fitur ini diam saja sampai operator memilih memakainya, jadi tidak ada langkah migrasi dan tidak ada jeda ketika pelanggan kehilangan akses.
Bisakah pelanggan melihat sisa kredit mereka sendiri?
Lewat pemeriksaan saldo, bisa. Begitu batasnya ditetapkan, saldo melaporkan sisa total mereka yang sebenarnya, bukan lagi nilai penanda lama, sehingga angkanya menurun seiring mereka bekerja. Rincian per keranjang lain soal: ia memerlukan token admin dan mengembalikan semua kunci sekaligus, jadi tampilkan dari dasbor Anda sendiri alih-alih membuka endpoint itu kepada pelanggan.
Token admin saya hilang. Sekarang bagaimana?
Buat yang baru di panel pengaturan yang sama. Token lama langsung berhenti bekerja, jadi tidak ada langkah pembersihan dan tidak ada jeda ketika keduanya sama-sama berlaku. Pelanggan Anda tidak terpengaruh: kunci mereka tidak tersentuh dan mereka terus memecahkan CAPTCHA. Yang rusak hanyalah proses penerbitan milik Anda sendiri, sampai Anda memperbarui rahasia yang dibaca handler webhook Anda.
Versi paling singkatnya
Aktifkan Remote Key Management satu kali dan simpan token bersama rahasia penagihan Anda yang lain. Tambahkan kunci bernama pelanggan ketika langganannya aktif, lengkap dengan grants paketnya sekalian, dan perlakukan 409 pada pengiriman ulang sebagai keberhasilan. Setel ulang atau tambah batas itu dari webhook perpanjangan Anda, sebab tidak ada apa pun di sini yang berjalan mengikuti kalender. Jalankan endpoint usage secara terjadwal, baik untuk mencocokkan tagihan maupun untuk menemukan kunci menganggur. Hapus berdasarkan nama ketika langganannya berakhir, dan bandingkan daftar kunci dengan pelanggan aktif Anda, sebab hanya di situlah jawaban sebenarnya berada. Lalu pasang proxy di depan dan jauhkan jalur admin dari port yang bisa dilihat pelanggan Anda. Lakukan itu dan bypass captcha menjadi sesuatu yang bisa Anda jual kembali di perangkat keras Anda sendiri, terukur dengan angka Anda sendiri, dan diterbitkan secepat checkout Anda bisa memicu sebuah webhook.
