A CAPTCHA you draw — privacy-first, AI-proof, drop-in.
Image CAPTCHAs are solved by AI in milliseconds — and every "pick the buses" click quietly labels someone else's training data. This is the opposite: the visitor draws a gesture for ~10 seconds, an AI reads the motion of a human hand (speed variance, pauses, micro-corrections), and your form gets a token — the same integration shape as reCAPTCHA.
- 🖐️ Draw, don't click — no image grids, no "select all traffic lights".
- 🔒 No tracking, no biometrics stored — raw gesture coordinates never leave the browser; only derived statistics. The widget is an iframe on our origin, so nothing about your visitors touches a third-party cookie.
- 🧩 Drop-in — two lines of HTML, one server-side call. Works with any stack.
- 🆓 Free tier — 1,000 verifications / month.
Live demo: https://homosapience.org/embed/captcha-demo.html Docs: https://homosapience.org/developers
<script src="https://homosapience.org/embed/v2/aptogon.js"></script>
<div data-aptogon-captcha data-aptogon-key="pk_live_YOUR_KEY"></div>Put the <div> inside the <form> you want to protect. On success the loader adds
a hidden <input name="aptogon-response"> to the form, so a normal submit carries
the token to your backend.
Never expose your secret key in the browser.
curl -s https://homosapience.org/api/captcha/siteverify \
-H "Authorization: Bearer sk_live_YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"token": "<aptogon-response from the submitted form>"}'{ "success": true, "human": true, "band": "community",
"hostname": "https://your-site.com", "issued_at": 1732801234 }Only accept the request when success and human are true. Tokens are
single-use (a replay returns 409) and expire in 120 seconds.
- Verify your domain in the console (DNS-TXT or a well-known file).
- Create an API key with that domain in its allowed origins → you get
pk_live_(public) +sk_live_(secret, shown once). - Paste the two lines. Done.
pk_live_ is safe in the browser and is bound to your domain — useless from any
other origin. sk_live_ is a secret: keep it in an environment variable on your
server, never in client code or git.
Full working snippets in examples/:
| Stack | File |
|---|---|
| Plain HTML | examples/index.html |
| React | examples/react.jsx |
| Node / Express | examples/node-express.js |
| Python / Flask | examples/python-flask.py |
| PHP | examples/php.php |
It raises the bar, it is not unbreakable. A funded adversary could eventually mimic gesture dynamics — the same is true of any software proof-of-human. It does not, on its own, stop distributed residential-proxy floods (specialized enterprise tooling is stronger there). For "keep bots off my signup / login / contact form without a privacy tax," it is a clean swap for image CAPTCHAs.
Every real gesture also helps train the classifier — so it improves as more humans use it. Raw coordinates are never stored; only derived, non-identifying statistics.
The <script> loader injects an <iframe> served from homosapience.org. Because
the iframe runs on our origin, its network calls are same-origin — your visitors'
data never touches a third-party context, and the cross-origin lock never triggers.
Your site is authenticated by the publishable key ↔ allowed-origins binding.
The gesture is classified server-side; the widget hands your page a short-lived
signed token; your backend confirms it with your secret key. That confirmation is
the only billable call.
AGPL-3.0-or-later. The full APTOGON source lives at https://github.com/tulubyev/homosapience.
The loader (aptogon.js) is served from our CDN and must be loaded from
https://homosapience.org — the same-origin iframe is the whole point of the
privacy model, so there is no npm package to self-host. This repo is a showcase and
integration-example collection; open an issue with feedback or edge cases where the
check misfires.