PrivCaptcha.com

Comment spam protection that does not track your readers

Comment spam is link placement at scale: one URL pushed into thousands of threads.

How comment spam gets posted

The tool crawls once for the form action and field names, then replays a POST. No JavaScript runs, no images load, and the article is often never fetched.

What spam comments looks like in your logs
Comments on years-old posts that get no readers.
More POSTs to the comment endpoint than GETs of those pages.
The same URL in unrelated threads within minutes, under different names.

How PrivCaptcha stops spam comments

Four steps, with the numbers the server uses. Nothing here is configured by you.

The direct POST carries no token

Most comment spam runs no JavaScript, so privcaptcha-response arrives empty, siteverify answers missing-input-response, and the post is refused before moderation.

A scraped sitekey mints nothing

Sitekeys are public, so assume yours is collected. Once you list your domains, any other Origin is refused with invalid-input-origin.

The bare poster starts at level 4

20 for an HTTP client, 40 for a bot User-Agent, 15 for no Accept-Language: 75, level 4, 10 shapes, 6 pixels, 10 degrees.

One token buys one comment

A token is spent by the comment it authorises. It expires 120 seconds after minting, so hundreds of threads is hundreds of challenges.

What a spam comments run costs now: Each post needs a challenge at 75: on the default 12-to-20 bit band, 18 bits, 2^18 SHA-256 hashes, 16 times a visitor's 14 bits. Paid again every post.

Add PrivCaptcha to your comment form in two lines of code

Script tag, container in front of the submit button, and your existing verify call. Already on reCAPTCHA or hCaptcha? That backend code stays exactly as it is.

reCAPTCHA siteverify hCaptcha siteverify
Server SDKs
<!-- comment form -->
<script src="https://privcaptcha.com/1/api.js" async defer></script>
<div class="privcaptcha" data-sitekey="your-site-key"></div>
<!-- server side, unchanged -->
POST https://privcaptcha.com/api/v1/siteverify
Where it goes

In the comment form above submit, and on every route accepting a public string.

What the backend does

Verify privcaptcha-response server-to-server in the comment handler before the insert. If success is false, reject.

The usual mistake

Reply boxes injected after load never get a widget: call privcaptcha.render() on the node.

What this does not solve about spam comments

A challenge gates automation, not content. It will not stop someone pasting links by hand, and nothing here reads the comment. Filtering and moderation stay yours.

Common questions about spam comments

How PrivCaptcha prices spam comments, and what it does not do about it.

Comment forms are exactly where a heavy challenge costs participation, which is why difficulty follows the request: an ordinary reader gets the quick version, and only automated-looking clients meet tight tolerances.
Yes. It is the same widget and the same verification call wherever you put it - comment threads, contact forms, reviews and support inboxes.
Every request is challenged - there is no invisible pass to aim a script at, and no allowlist that skips the check. What changes is the form the challenge takes and what it costs. The server scores each request and picks one of five difficulty levels, so an ordinary visitor gets a couple of seconds and a client that looks automated gets tight tolerances and a heavier proof-of-work. On the non-visual path, taken by screen-reader and keyboard visitors, there is no puzzle to solve at all: the proof-of-work is the whole challenge, at a fixed 22 bits.
No. An address is used for the length of one request and never written anywhere. What we keep is an HMAC of it under a salt that is random, lives only in Redis and rotates every day, so yesterday's hashes cannot be linked to today's. The counters under that hash expire after 24 hours.

Put PrivCaptcha in front of your comment form

10,000 verifications a month are free, and the integration is the one you already have.