Python
A single file with no packaging: copy sdk/python/privcaptcha.py into your project. Its only
dependency is httpx.
pip install httpx
Verify
import os
from privcaptcha import verify
result = verify(
secret=os.environ["PRIVCAPTCHA_SECRET"],
response=request.form["privcaptcha-response"],
remote_ip=request.remote_addr,
)
if not result.success:
abort(400, result.error_codes)
VerifyResult carries success, challenge_ts, hostname and error_codes, and is
truthy exactly when success is true — if not result: works too.
| Argument | Default | Description |
|---|---|---|
secret |
— | your site secret |
response |
— | the token from the form field |
remote_ip |
None |
the visitor's IP, sent as remoteip |
endpoint |
https://privcaptcha.com/api/v1/siteverify |
override for testing |
timeout |
10.0 |
seconds |
Async
from privcaptcha import averify
result = await averify(secret=SECRET, response=token)
Same arguments, same result type.
Fail-closed behaviour
Any HTTP error — timeout, connection failure, non-200 — returns
VerifyResult(success=False, error_codes=["verification-unavailable"]) rather than raising.
A verifier that returns success when it cannot verify is one outage away from being an open
door, so the failure is never silent and never permissive. If you want to distinguish an
outage from a bad token, check for that code.
An empty response short-circuits to missing-input-response without a network call.
See Verify a token for the endpoint itself.