Migrate from GeeTest to CaptchaLa
Self-serve pricing, English-first docs, and a single token instead of four hidden fields. Switch in under 10 minutes.
What the code change looks like
<div id="captcha"></div>
<script src="https://static.geetest.com/v4/gt4.js"></script>
<script>
initGeetest4({ captchaId: 'YOUR_CAPTCHA_ID' }, function(captcha) {
captcha.appendTo('#captcha')
captcha.onSuccess(function() {
var result = captcha.getValidate()
document.getElementById('lot_number').value = result.lot_number
document.getElementById('captcha_output').value = result.captcha_output
document.getElementById('pass_token').value = result.pass_token
document.getElementById('gen_time').value = result.gen_time
})
})
</script><div class="captchala" data-app-key="YOUR_APP_KEY"></div>
<script src="https://cdn.captcha.la/v1/captchala.js" async defer></script>const sign = crypto.createHmac('sha256', process.env.GEETEST_KEY)
.update(req.body.lot_number).digest('hex')
const res = await fetch(`https://gcaptcha4.geetest.com/validate?captcha_id=${process.env.GEETEST_ID}`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
lot_number: req.body.lot_number,
captcha_output: req.body.captcha_output,
pass_token: req.body.pass_token,
gen_time: req.body.gen_time,
sign_token: sign,
}),
})
const data = await res.json()
if (data.result !== 'success') return res.status(400).json({ error: 'bot' })const res = await fetch('https://api.captcha.la/v1/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
appSecret: process.env.CAPTCHALA_SECRET,
token: req.body['captchala-token'],
}),
})
const data = await res.json()
if (!data.success) return res.status(400).json({ error: 'bot' })Migration steps
- 1
Sign up & grab your App Key + Secret
Create a free CaptchaLa account — no sales call, no contact form. Add a site, copy the App Key (public) and App Secret (server-side).
- 2
Remove the GeeTest initialization JS
Delete the initGeetest4 invocation and its onSuccess callback. Drop the four hidden inputs (lot_number, captcha_output, pass_token, gen_time) you were populating.
- 3
Add the CaptchaLa widget tag
Replace the entire GeeTest block with our div + script. No JS configuration needed — the widget self-initializes from data-app-key.
- 4
Simplify the server verify
Replace the GeeTest verify (with its HMAC sign_token computation, four-field body, and result string check) with a single JSON POST to api.captcha.la/v1/verify and a success boolean.
- 5
Roll out gradually
Switch one form at a time. Watch conversion and challenge rate. There's no minimum or contract, so a staged rollout is free.
Frequently asked questions
Will CaptchaLa work as well in mainland China?
Yes. We operate native endpoints inside mainland China — the same low-latency verification real users get elsewhere. No different SDK, no separate billing.
What about GeeTest's slider UX my team is used to?
CaptchaLa includes slider as one of the challenge types in the adaptive system — it's not the default, but it's available. Most teams find the default (invisible for low-risk + click for higher-risk) converts better than slider-first.
Are there differences in risk scoring sensitivity?
GeeTest's risk model is tuned for APAC traffic patterns. CaptchaLa's is global. If your traffic is APAC-heavy, expect comparable behavior. If you're outside APAC, you may see a meaningful drop in false positives.