Migration guide

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.

GeeTestCurrent setup~10 minCaptchaLaDrop-in target

What the code change looks like

Before — GeeTest GT4
<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>
After — CaptchaLa
<div class="captchala" data-app-key="YOUR_APP_KEY"></div>
<script src="https://cdn.captcha.la/v1/captchala.js" async defer></script>
Before — GeeTest server verify (Node)
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' })
After — CaptchaLa server verify (Node)
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. 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. 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. 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. 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. 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.