PrivCaptcha.com

Fake account and bot signup prevention for registration forms

Someone runs your registration form in a loop to mint disposable accounts for trial credits, free tiers and referral bounties.

How signups get created in bulk

Scrape the form once, then loop: post it, pull the confirmation link from a catch-all mailbox, claim the bounty, discard the account. Half the attempts can fail while each is nearly free.

What fake signups looks like in your logs
Registrations climb while day-two activity does not.
One invite code redeemed hundreds of times in an hour.
Thousands of accounts behind a few catch-all domains.

How PrivCaptcha stops fake signups

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

Refused before a challenge exists

Once your domains are listed, a farm calling /api/v1/challenge with a scraped sitekey is refused: invalid-input-origin. It must run a real browser per account.

Account one is already level 4

No warm-up: scoring happens on the challenge request. Everyone starts at 20; the HeadlessChrome user-agent adds 40; 60 is level 4, 17 bits.

Failure compounds across the run

A clean browser starts at 20: level 2, 6 shapes. Each failed challenge adds 8. The fifth caps it at 60, level 4.

Tokens cannot be stockpiled

A token lives 120 seconds and the verify spends it, so one token creates one account.

What a fake signups run costs now: Ten thousand accounts was an afternoon's work. Now a headless user-agent scores 20 + 40 = 60: 17 bits, roughly 131,000 SHA-256 hashes, plus a level-4 solve, 10 shapes or 6 pixels.

Add PrivCaptcha to your registration 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
<!-- registration 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

On the step that writes the account row, not email capture.

What the backend does

Post privcaptcha-response to /api/v1/siteverify server-to-server and require success:true before the INSERT.

The usual mistake

Do not render the widget on step one and verify at the end: the token expires 120 seconds after solving.

What this does not solve about fake signups

Hand-registered accounts and paid solving services still get through. It guards only the form it renders on, not your signup API. Daily counters reset, so a proxy pool restarts at 20.

Common questions about fake signups

How PrivCaptcha prices fake signups, and what it does not do about it.

No captcha does. What it does is remove the free path: every registration solves a puzzle and pays a proof-of-work, so creating accounts in bulk stops being cheap enough to be worth automating.
Almost always. 10,000 verifications a month is far more registrations than most products see.
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 registration form

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