“How do I add a CAPTCHA to an HTML form?”
How do I add a CAPTCHA to an HTML form?
Short answer
With three pieces: a script tag that loads the widget, a div where the game renders, and a server route that verifies the token before you act on the form. CaptchaKit's widget writes a signed token into the div's data-token attribute when the visitor passes. You copy it into a hidden field on submit, send it with the form, and your server posts it to the verify endpoint with your secret key. Verification needs a backend, because the secret key must never ship to the browser.
Steps
- 1
Embed the widget
Add the script tag for widget.js and, inside your form, a div with data-gamecaptcha, your site key and a game. That is the entire front-end install.
- 2
Copy the token on submit
When the visitor passes, the widget stores the signed token in the div's data-token attribute. On submit, copy it into a hidden input named gamecaptchaToken so it posts with the rest of the form.
- 3
Verify on your server
In your form handler, POST the token and your site key to https://captchakit.com/api/verify with an Authorization: Bearer header holding your secret key. If success is false, reject the submission.
The HTML
A minimal form with the widget. Replace the site key with your own from the dashboard, and keep the secret key in a server-side environment variable.
<script src="https://captchakit.com/widget.js"></script>
<form method="POST" action="/signup">
<input type="email" name="email" required>
<div data-gamecaptcha
data-site-key="gc_connect4_your_key_here"
data-game="connect4"></div>
<input type="hidden" name="gamecaptchaToken" value="">
<button type="submit">Sign up</button>
</form>
<script>
document.querySelector('form').addEventListener('submit', () => {
const token = document.querySelector('[data-gamecaptcha]').dataset.token;
document.querySelector('[name=gamecaptchaToken]').value = token || '';
});
</script>The server check
An Express handler as an example. The same three lines of logic work in any language, and the docs show Node, Python and PHP.
app.post('/signup', async (req, res) => {
const { email, gamecaptchaToken } = req.body;
const verify = await fetch('https://captchakit.com/api/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.CAPTCHAKIT_SECRET_KEY}`,
},
body: JSON.stringify({
token: gamecaptchaToken,
siteKey: process.env.CAPTCHAKIT_SITE_KEY,
}),
});
const { success } = await verify.json();
if (!success) return res.status(400).send('Captcha failed');
// token is valid, create the account
res.send('OK');
});What if my site has no backend?
The verify call needs a server you control, because the secret key that authorizes it must stay out of the browser. Static sites usually solve this with a small serverless function that holds the key in an environment variable and proxies the one POST. On WordPress, the CaptchaKit plugin does the verification for you.
Choosing a game and theme
The div's data-game attribute picks the challenge, for example connect4 or whackabot, and data-theme accepts dark or light. If you enable more than one game, the widget shows a Switch game button so visitors can choose. The full game list with best-for hints is in the docs.
Tokens are single use and expire after 10 minutes, so verify each submission once, promptly. See CAPTCHA token expired or already used if you are debugging that.
Questions
Do I need JavaScript?
A few lines, shown above, to copy the token into the form. The game itself runs in an iframe the widget injects.
Where do I get the keys?
The site key comes from your dashboard and is public. The secret key goes in a server-side environment variable, never in the page.
Can I send the token as JSON instead of a form POST?
Yes. Send a field named gamecaptchaToken in your JSON body, like the React example in the docs.
Does this work on a static site?
The widget does. The verify call needs a small server or function so the secret key stays private.
What is the token field called?
gamecaptchaToken in the request your server receives. The widget exposes it as data-token on its div.
How long is the token valid?
10 minutes, and it can be verified once.
Can I use it on a contact form?
Yes, and contact forms are a common fit. See the signup and contact form guide.
Sources
- CaptchaKit documentation (checked 2026-10-18)
- CaptchaKit WordPress plugin (checked 2026-10-18)
Related
Protect your forms with a game
Every arcade CAPTCHA we make. Sign up, grab your embed code, protect your forms today.
Get started →Pay what you want. Start free.