Quickstart
This guide will help you integrate CaptchaLa CAPTCHA in 5 minutes.
See it work in 30 seconds
demo-v1.captcha.la — pure HTML + PHP, MIT-licensed, view-source on every page.
- popup.html — popup mode
- float.html — floating widget
- bind.html — bind to button
- inline.html — inline embed
- server-token.html — server-issued token (anti-replay)
1. Create Account
Sign up for a free account in the dashboard
2. Create Application
Create an app in the dashboard to get your App Key
3. Install SDK
Choose your preferred installation method
<!-- CDN loader (recommended): auto-fallback CDN, ~6 KB gzip -->
<script src="https://cdn.captcha-cdn.net/captchala-loader.js"></script># or via npm
npm install captchala4. Initialize CAPTCHA
Initialize the CAPTCHA component in your page
<button id="login-btn">Sign in</button>
<script>
loadCaptchala(function () {
Captchala.init({
appKey: 'YOUR_APP_KEY',
product: 'bind', // popup | float | bind | embed
action: 'login',
lang: 'auto',
})
.onSuccess(function (res) {
// res.token starts with pt_ — POST it to your backend
submitLogin(res.token);
})
.onError(function (err) { console.error(err.message); })
.bindTo('#login-btn'); // popup/bind use bindTo; float/embed use appendTo
});
</script>5. Server Verification
Verify the token on your server
POST https://apiv1.captcha.la/v1/validate
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json
{ "pass_token": "<from onSuccess>", "client_ip": "<end-user IP>" }{
"code": 0,
"data": {
"valid": true,
"action": "login",
"challenge_id": "ch_xxx",
"uid": null,
"client_ip": "1.2.3.4",
"risk_score": 12
}
}WARNING
Always check data.valid === true and data.action matches the scene you expected. Pass tokens are single-use; the same pt_xxx cannot be validated twice.
Server-issued Token Mode (recommended for production)
For sensitive actions (login, register, payment) we recommend the server-issued token flow: your backend first requests a short-lived server_token, which the browser then uses to initialize the CAPTCHA. This prevents abuse from a leaked app_key.
When to use
- Recommended: register, login, password reset, payment, points redemption, and any endpoint an attacker can script.
- Optional: casual public forms, search boxes, and low-value interactions where convenience matters more.
1. Backend issues server_token
Call /v1/server/challenge/issue from your own server, using the X-App-Key and X-App-Secret headers. Never expose these headers to the browser.
# Server-side only — never call this from a browser
curl -X POST https://apiv1.captcha.la/v1/server/challenge/issue \
-H "X-App-Key: YOUR_APP_KEY" \
-H "X-App-Secret: YOUR_APP_SECRET" \
-d "action=login&ttl=300&max_uses=1&bind_ip=1.2.3.4"
# → { "code": 0, "data": { "server_token": "sct_...", "expires_in": 300 } }2. Frontend renders CaptchaLa with the server_token
Pass the token to your CaptchaLa component. The SDK forwards it to the challenge initialization when initializing the challenge.
// Browser fetches the token from YOUR backend, not from CaptchaLa directly
const { serverToken } = await fetch('/api/captcha/issue').then(r => r.json());
Captchala.init({
appKey: 'YOUR_APP_KEY',
serverToken, // single-use, short-lived
product: 'popup',
action: 'login',
})
.appendTo('#captcha-container')
.onSuccess(res => submitForm(res.token));Security notes
- Never put app_secret in frontend code, mobile apps, or public repositories. It must stay server-side.
- Enable "Require server-issued challenge token" in the dashboard to reject any challenge attempted without a server_token.
- Keep ttl short (300s default, 900s max) and prefer max_uses=1 to reduce the impact of token leakage.