Manav Human Check drops into the exact spot your captcha sits — the same 300px box. By default a press-&-hold proves a live person with zero saved to the device — no passkey, no images, no farm shortcut. Need hardware-grade proof? Opt into a one-tap passkey.
↑ this pane is live. press & hold it.
Captchas fail because any puzzle an AI can see, an AI can solve. So we don't use a puzzle — and by default we don't enroll anything either. We just prove a live person is here, right now.
The same box your users already recognise from reCAPTCHA or Turnstile. Press and hold for a moment — nothing to read, nothing to drag.
A sustained hold from genuine hardware input proves a live person. Synthetic bot events (isTrusted:false) are rejected. No passkey is created and nothing is saved to the device. Need hardware-grade proof? data-assurance="strong" swaps this step for a one-tap passkey.
A one-time, Ed25519-signed token rides the form submit. Verify it server-side — or offline against the published key — and keep it as proof.
Light, dark, normal, compact, flexible — match your form. The first three are the zero-storage default; the last opts into the strong passkey. Each pane is a single <div class="manav-check">.
The first three panes press-&-hold and store nothing. The last opts into a one-tap device passkey (data-assurance="strong"); a desktop without one gets a phone-QR hand-off.
Every pass returns a compact, signed receipt. Check it on your server, or anywhere, against the public key we publish — no callback to Manav required.
// GET …/.well-known/ → the public key, by design { "alg": "ed25519", "offlineVerifiable": true, … } // the signed receipt your form carries on submit { "type": "bind", "anchor": "webauthn_uv", "human": true, "alg": "ed25519", "sig": "NKmjr8qHOVxP7Iqfg1WO…" }
A passkey is the strong path, but it degrades gracefully so no genuine user hits a wall — and you decide how strict to be.
data-attestation="required"Touch ID / Face ID / Windows Hello — the gold path.
No local authenticator? A QR pairs your phone to finish the check.
Behavioral entropy + isTrusted input, clearly labelled weaker.
The form factor matches the incumbents, so swapping is a markup change. What differs is the test underneath: a hardware passkey gesture instead of a solvable puzzle.
| reCAPTCHA v2 | hCaptcha | Turnstile | Manav | |
|---|---|---|---|---|
| Normal size | 304×78 | ~303 wide | 300×65 | ~300×66 |
| Compact | 158×140 | yes | 150×140 | 150×140 |
| Themes | light/dark | light/dark | auto/light/dark | auto/light/dark |
| The test | image puzzle / risk | image puzzle | JS challenge | passkey gesture |
| Solvable by AI vision | yes | yes | n/a | no |
| Proof you can keep | token (server-checked) | token | token | signed, offline-verifiable |
This is a recognised direction: Cloudflare shipped Cryptographic Attestation of Personhood — touch a hardware key instead of a captcha, validated against the FIDO Metadata Service — on the same premise. Manav packages it as a drop-in pane with a portable, offline-verifiable receipt and graceful fallbacks. Honest limit: a passkey gesture is strong evidence of a human, and the residual bypass (a virtual/automation authenticator) is what data-attestation="required" shuts out.
The browser runs the ceremony; the server owns the part the browser can't be trusted with — a tamper-evident, signed receipt.
The decisive step asks the device's secure enclave to assert presence with a real fingerprint, Face ID, or PIN — a prompt owned by the operating system, with no API to fake a fingerprint into a genuine authenticator. The server signs each receipt and chains it (head = sha256(receipt | sig)), so a bot that splices, drops, or replays a step breaks the chain and can't forge a new one. Rate limits are keyed on CF-Connecting-IP; every verify token is one-time-use.
<!-- default: zero-storage press-&-hold, nothing saved on the device --> <div class="manav-check" data-theme="auto" data-size="normal" data-endpoint="/labs/captcha/api/index.php"></div> <!-- opt in to a hardware passkey (one tap; phones save a synced passkey) --> <div class="manav-check" data-assurance="strong" data-endpoint="/labs/captcha/api/index.php"></div> <script src="/labs/captcha/widget.js"></script> // on submit, the form carries a hidden "manav-token" — check it server-side: // POST /labs/captcha/api/index.php?action=verify { token } // → { human:true, anchor:"webauthn_uv", attested:false } (one-time use)
Options: data-assurance="strong" (device passkey), data-attestation="required" (genuine devices only), data-ttl="300" (expire & re-arm), data-size="compact|flexible".
Indicative tiers for this demo — the pane, the API, and the receipts are fully open here.
data-attestation="required" additionally shuts out virtual/automation authenticators.Drop in two lines and verify a real human on the very next submit. No images, no friction, a receipt you can keep.