Developer Documentation
Everything you need to integrate doCaptcha. Web, iOS, and Android, plus a copy-paste prompt for AI assistants. Up and running in under five minutes.
Quick start
Four steps, top to bottom.
Get your keys
Create a free account and copy your site key (public, goes in the page) and secret key (private, stays on your server) from the dashboard.
Site key: sk_live_xxxxxxxxxxxxxxxx
Secret key: sec_xxxxxxxxxxxxxxxx
Add the script
Load the widget bundle once per page. It is a single async script with no dependencies.
<script src="https://widget.docaptcha.com/v1/widget.min.js" async></script>
Drop the widget into your form
Add one div with your site key inside the form. It auto-mounts and writes a hidden docaptcha-token field on success, so a normal submit carries the token.
<form action="/submit" method="post">
<div data-docaptcha-sitekey="sk_live_xxxx"></div>
<button type="submit">Submit</button>
</form>
Verify on your server
From your backend, confirm the token with your secret key. Treat success:false (or a low score) as a failed check. Never call this from the browser.
POST https://api.docaptcha.com/api/v1/api/v2/captcha/siteverify
{ "secret": "sec_xxxx", "token": "<docaptcha-token>" }
// → { "success": true, "hostname": "...", "score": 0.92 }
Integrate with AI
Using an AI assistant like ChatGPT, Claude, or Cursor? Copy this prompt, replace your keys, and let it wire doCaptcha into your app. For machine-readable docs, point your tool at docaptcha.com/llms.txt.
Integrate doCaptcha (privacy-first, GDPR-native bot protection) into my app.
Frontend: load <script src="https://widget.docaptcha.com/v1/widget.min.js" async></script> once, then put <div data-docaptcha-sitekey="MY_SITE_KEY"></div> inside the form I want to protect. The widget auto-mounts and adds a hidden input named "docaptcha-token" to the form on success.
Backend: after the form is submitted, verify the token server-side:
POST https://api.docaptcha.com/api/v1/api/v2/captcha/siteverify
Content-Type: application/json
{ "secret": "MY_SECRET_KEY", "token": "<the docaptcha-token from the form>" }
Response: { "success": boolean, "hostname": string, "score": number }
Reject the submission if success is false. Keep MY_SECRET_KEY on the server only.
Optional locale: add data-docaptcha-lang="de" (or fr) to the div for a localized widget.
Please wire this into my existing form and backend, keeping my current framework and style.Complete example
1. Drop the widget into your form. It auto-mounts and, on success, injects a hidden docaptcha-token field, so a normal form POST carries the token. No JavaScript required.
<!DOCTYPE html>
<html>
<head>
<title>doCaptcha Integration</title>
</head>
<body>
<!-- The widget injects a hidden "docaptcha-token" field into
this form on success, so a normal POST carries the token. -->
<form action="/submit" method="post">
<input type="email" name="email" placeholder="Email" required>
<!-- doCaptcha widget -->
<div data-docaptcha-sitekey="sk_live_1234567890abcdef"></div>
<button type="submit">Submit</button>
</form>
<!-- Auto-mounts every [data-docaptcha-sitekey] on the page -->
<script src="https://widget.docaptcha.com/v1/widget.min.js" async></script>
</body>
</html>
2. On your backend, verify the token with your secret key before trusting the submission:
// Node.js — after the form POST reaches /submit
const res = await fetch(
'https://api.docaptcha.com/api/v1/api/v2/captcha/siteverify',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.DOCAPTCHA_SECRET, // sec_...
token: req.body['docaptcha-token'],
}),
}
);
const { success } = await res.json();
if (!success) {
return res.status(400).send('CAPTCHA verification failed');
}
// ...proceed: the request is human-verified
That is the whole loop: the widget on the page, one siteverify call on your server.
API reference
/api/v1/api/v2/captcha/siteverifyVerify a token server-side. Call this from your backend with your secret key and the docaptcha-token submitted with the form. Always returns HTTP 200; check the success field.
// Request body
{
"secret": "sec_your_secret_key",
"token": "the docaptcha-token from your form"
}
// Response
{
"success": true,
"hostname": "yourdomain.com",
"challenge_ts": "2026-05-31T12:00:00Z",
"score": 0.9
}
/api/v1/api/v2/form/validateOptional server-side form-quality validation (Pro/Enterprise): content scoring, disposable-email blocking, and Redis-backed rate limiting.
{
"siteKey": "sk_live_xxxx",
"fields": { "email": "...", "message": "..." }
}
Smart Form Protection
Protect forms from spam & abuse
Beyond CAPTCHA: SmartFormGuard detects gibberish, blocks disposable emails, enforces fill-time minimums, and rate-limits repeat submissions. Available on Pro and Enterprise plans.
<!-- 1. Include the SDK -->
<script type="module">
import { SmartFormGuard } from 'https://api.docaptcha.com/sdk/smart-form-guard.js';
const guard = new SmartFormGuard({
siteKey: 'dc_live_1234567890abcdef',
apiUrl: 'https://api.docaptcha.com',
minFillTime: 3000, // 3 seconds minimum
maxSubmissions: 3, // per 5-minute window
});
// Auto-protect: injects honeypot, tracks timing, validates on submit
guard.protect(document.getElementById('contactForm'));
// Listen for validation results
document.getElementById('contactForm')
.addEventListener('dcFormError', (e) => {
console.log('Blocked:', e.detail.errors);
});
</script>
<!-- 2. Your form (no changes needed) -->
<form id="contactForm" action="/submit" method="post">
<input type="text" name="name" placeholder="Name" required>
<input type="email" name="email" placeholder="Email" required>
<textarea name="message" placeholder="Message" required></textarea>
<button type="submit">Send</button>
</form>
Client-side checks
- Honeypot field injection
- Fill-time enforcement
- Gibberish & name validation
- Disposable email blocking
- Local rate limiting
Server-side validation
- POST /api/v1/api/v2/form/validate
- Content quality scoring
- Redis-backed rate limiting
- Configurable per-site thresholds
- Silent honeypot acceptance
Mobile SDK for iOS & Android
Native bot protection with no WebView. The SDK collects permission-free device signals and solves the proof-of-work on-device. Invisible, no puzzles, no embedded browser. Available on Pro and Enterprise plans.
Add the Swift package: https://gitlab.com/applox/docaptcha/docaptcha-ios-sdk.git
import DoCaptcha
let client = DoCaptchaClient(siteKey: "sk_live_yourSiteKey")
do {
let token = try await client.verify()
// Send token to YOUR backend, it calls /siteverify
try await api.submit(captchaToken: token)
} catch let error as DoCaptchaError {
print(error.localizedDescription)
}
Verify on your server
The token is single-use. Confirm it from your backend with your secret key, the same siteverify call the web widget uses. Never ship the secret key in the app.
curl -X POST https://api.docaptcha.com/api/v1/api/v2/captcha/siteverify \
-H "Content-Type: application/json" \
-d '{"secret":"sec_yourSecretKey","token":"<token from the app>"}'
# → { "success": true, "challenge_ts": "…", "hostname": "…", "score": 0.82 }