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.

1

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
2

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>
3

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>
4

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

POST/api/v1/api/v2/captcha/siteverify

Verify 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
}
POST/api/v1/api/v2/form/validate

Optional 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 }

Ready to get started?

Create your free account and start protecting your app today.