API Tutorials

Cara Solve Cloudflare Turnstile dengan API

Turnstile tidak pernah menampilkan puzzle atau kotak centang. Yang terjadi di balik layar: CaptchaAI membaca sinyal browser itu lewat API dan mengembalikan token cf-turnstile-response yang tinggal disuntik ke form target Anda — biasanya dalam kurang dari 10 detik.

Panduan ini untuk tim otomasi dan QA yang form-nya harus tetap bisa disubmit lewat script, bukan dibuka satu-satu secara manual. Anda akan mengikuti alur yang sama dengan integrasi CaptchaAI lain: kirim task, simpan ID-nya, polling, lalu pakai token. Kalau belum pernah pakai API CaptchaAI sama sekali, mulai dari panduan quickstart dulu supaya empat langkah ini terasa familiar.


Yang Anda perlukan sebelum mulai

Siapkan empat hal ini sebelum masuk ke Langkah 1 — tanpa salah satunya, task akan ditolak backend CaptchaAI:

Item Nilai
API key CaptchaAI Dari dashboard di captchaai.com
Sitekey Turnstile Diekstrak dari halaman target (diawali 0x)
URL halaman URL lengkap tempat Turnstile muncul
Bahasa Python 3.7+ atau Node.js 14+

Langkah 1: Cari sitekey Turnstile di halaman target

Sitekey biasanya nongol di HTML halaman, di dalam tag div atau script:

<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>

Atau di-render lewat JavaScript:

turnstile.render('#widget', {
  sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
  callback: function(token) { /* ... */ }
});

Tiga cara mengambilnya kalau tidak langsung terlihat:

  • DevTools browser — buka tab Elements, cari data-sitekey atau cf-turnstile.
  • Lihat sourceCtrl+U, cari string yang diawali 0x.
  • Tab Network — filter request ke challenges.cloudflare.com; sitekey ada di parameternya.

Sitekey Turnstile selalu diawali 0x dan panjangnya sekitar 22 karakter — beda pola dari sitekey reCAPTCHA yang mulai dengan 6L.


Langkah 2: Kirim task ke API CaptchaAI

Task-nya sederhana: POST ke https://ocr.captchaai.com/in.php dengan method=turnstile, sitekey, dan pageurl.

import requests

API_KEY = "YOUR_CAPTCHAAI_KEY"
SITEKEY = "0x4AAAAAAAC3DHQFLr1GavNl"
PAGEURL = "https://staging.example.com/qa-login"

r = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": SITEKEY,
    "pageurl": PAGEURL,
    "json": 1,
})
data = r.json()
if data["status"] != 1:
    raise RuntimeError(f"submit failed: {data}")
task_id = data["request"]
print("task id:", task_id)

Kalau stack Anda Node.js, logikanya identik:

const axios = require("axios");

const { data } = await axios.post("https://ocr.captchaai.com/in.php", null, {
  params: {
    key: process.env.CAPTCHAAI_KEY,
    method: "turnstile",
    sitekey: "0x4AAAAAAAC3DHQFLr1GavNl",
    pageurl: "https://staging.example.com/qa-login",
    json: 1,
  },
});
if (data.status !== 1) throw new Error(`submit failed: ${JSON.stringify(data)}`);
const taskId = data.request;

Kalau berhasil, respons-nya {"status": 1, "request": "<task_id>"}. Simpan task_id ini — dipakai di Langkah 3 untuk polling.


Langkah 3: Polling sampai token siap

Turnstile umumnya kelar dalam waktu kurang dari 10 detik. Beri jeda 10 detik dulu sebelum polling pertama, lalu ulangi tiap 5 detik sampai maksimum 40 kali percobaan:

import time

time.sleep(10)
for _ in range(40):
    r = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    })
    res = r.json()
    if res["status"] == 1:
        token = res["request"]
        break
    if res["request"] != "CAPCHA_NOT_READY":
        raise RuntimeError(f"solver error: {res}")
    time.sleep(5)
else:
    raise TimeoutError("turnstile solving timed out")

print("token (60 karakter pertama):", token[:60])

Token yang dikembalikan adalah string Base64, biasanya diawali 0. dan panjangnya 400–600 karakter.


Langkah 4: Suntik token ke form dan submit

Setelah token di tangan, masukkan ke field tersembunyi cf-turnstile-response pada form Turnstile, baru submit formnya.

Kalau pakai Selenium:

driver.execute_script(
    "document.querySelector('[name=cf-turnstile-response]').value = arguments[0];",
    token,
)
driver.find_element("css selector", "form").submit()

Kalau pakai Playwright:

page.evaluate(
    "(t) => document.querySelector('[name=cf-turnstile-response]').value = t",
    token,
)
page.click("button[type=submit]")

Kalau cuma request HTTP biasa: tambahkan cf-turnstile-response=<token> ke body application/x-www-form-urlencoded sebelum dikirim.

Token Turnstile hanya berlaku sekitar 120–300 detik. Pakai secepatnya setelah diterima — kalau kelamaan, backend target akan menolaknya dengan timeout-or-duplicate dan Anda harus solve ulang dari Langkah 2.


Contoh Python siap pakai

Gabungan keempat langkah di atas dalam satu fungsi, tinggal import dan panggil:

import os, time, requests

API = "https://ocr.captchaai.com"
KEY = os.environ["CAPTCHAAI_KEY"]

def solve_turnstile(sitekey: str, pageurl: str) -> str:
    r = requests.post(f"{API}/in.php", data={
        "key": KEY, "method": "turnstile",
        "sitekey": sitekey, "pageurl": pageurl, "json": 1,
    }, timeout=30)
    j = r.json()
    if j["status"] != 1:
        raise RuntimeError(f"submit: {j}")
    tid = j["request"]

    time.sleep(10)
    for _ in range(40):
        r = requests.get(f"{API}/res.php", params={
            "key": KEY, "action": "get", "id": tid, "json": 1,
        }, timeout=30)
        j = r.json()
        if j["status"] == 1:
            return j["request"]
        if j["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(f"poll: {j}")
        time.sleep(5)
    raise TimeoutError("timeout")

if __name__ == "__main__":
    print(solve_turnstile("0x4AAAAAAAC3DHQFLr1GavNl", "https://staging.example.com/qa-login"))

Kalau Turnstile gagal di-solve

Lima penyebab paling sering ditemui tim yang baru mengintegrasikan Turnstile — tidak berurutan, cek yang paling relevan dengan gejala Anda dulu:

  • Sitekey berubah tiap kunjungan. Sebagian situs Cloudflare menerbitkan sitekey baru setiap halaman dimuat ulang. Jangan hardcode — scrape ulang sitekey sebelum tiap task dikirim.
  • pageurl harus persis sama. Backend Turnstile mencocokkan URL secara ketat terhadap sitekey. Kirim path final apa adanya, tanpa query string tambahan yang tidak perlu.
  • Klien HTTP polos gampang ditolak Cloudflare. Kalau permintaan langsung (bukan lewat browser) sering kena block sebelum sempat submit token, pola koneksinya kemungkinan beda dari browser asli. Pindah ke curl_cffi, Playwright, atau browser sungguhan biasanya menyelesaikannya.
  • Token kedaluwarsa sebelum sempat dipakai. Solve-nya sukses tapi form Anda baru submit dua menit kemudian? Solve ulang saja, jangan paksakan token lama.
  • Jaringan lambat menambah risiko tantangan tambahan. Ini lebih terasa di koneksi mobile atau lewat IP datacenter murah. Pakai egress jaringan yang diotorisasi, dan kalau server Anda jalan dari region Asia Tenggara (mis. Singapura atau Jakarta), pastikan latensi ke ocr.captchaai.com stabil sebelum menyalahkan solver-nya.

Kode error yang sering muncul

Kalau task ditolak atau solve gagal, cek dulu tabel ini sebelum membuka tiket support:

Kode Arti Tindakan
ERROR_WRONG_USER_KEY Format API key salah Pastikan CAPTCHAAI_KEY disalin utuh, tanpa spasi tersisa
ERROR_KEY_DOES_NOT_EXIST API key tidak dikenali Salin ulang key langsung dari dashboard
ERROR_ZERO_BALANCE Saldo habis Top up saldo, lalu kirim ulang task
ERROR_PAGEURL Parameter pageurl hilang atau tidak lengkap Kirim URL penuh yang berawalan https://
ERROR_CAPTCHA_UNSOLVABLE Gagal setelah beberapa kali percobaan Cek kecocokan sitekey dan pageurl, lalu coba kirim task baru

Tabel error yang lebih lengkap ada di panduan solve reCAPTCHA v2 — kode-kodenya banyak yang sama lintas tipe CAPTCHA.


Pertanyaan seputar solve Turnstile via API

Apakah solve Turnstile lewat API CaptchaAI perlu proxy?

Tidak wajib. Submit task cukup butuh sitekey dan pageurl yang valid — beda dengan Cloudflare Challenge yang kadang perlu parameter proxy tambahan. Kalau situs target punya proteksi reputasi IP yang ketat, kualitas jaringan tetap berpengaruh ke kelancaran solve, bukan ke pemanggilan API-nya.

Kenapa token Turnstile saya ditolak padahal status solve sudah sukses?

Dua penyebab paling umum: token dipakai lewat dari masa berlakunya (sekitar 120–300 detik), atau pageurl yang dikirim saat submit task tidak persis sama dengan URL halaman form aslinya. Backend Turnstile mencocokkan token ke pageurl secara ketat.

Bisakah API ini dipakai untuk Turnstile di WebView aplikasi mobile?

Bisa, selama Anda tetap bisa mengekstrak sitekey dan pageurl dari halaman yang dirender WebView tersebut. Alurnya sama persis dengan browser desktop: kirim task, polling, lalu suntikkan token ke field cf-turnstile-response sebelum form disubmit.

Berapa thread yang idealnya dipakai untuk volume solve Turnstile harian?

Tergantung volume. Tim kecil yang baru uji coba biasanya cukup dengan BASIC ($15/bulan, 5 thread); begitu volume harian mulai stabil dan butuh solve paralel lebih banyak, naik ke STANDARD ($30/bulan, 15 thread) atau ADVANCE ($90/bulan, 50 thread). Karena tiap thread dapat solve tanpa batas, biaya bulanan tetap flat berapa pun jumlah task yang lewat.


Bacaan lanjutan

Komentar dinonaktifkan untuk artikel ini.