infopeak/captcha

Server-side verification for InfoPeak Captcha - the privacy-first, EU-hosted captcha. No tracking, no cookies, no puzzles.

Maintainers

Package info

github.com/infopeak/captcha-php

Homepage

Documentation

pkg:composer/infopeak/captcha

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-21 11:07 UTC

This package is auto-updated.

Last update: 2026-08-03 13:14:58 UTC


README

Server-side verification for InfoPeak Captcha - the privacy-first, EU-hosted captcha. No tracking, no cookies, no image puzzles.

Install

composer require infopeak/captcha

Requires PHP 7.4+ with the curl and json extensions.

Usage

Add the widget to your form (full guide):

<form action="/signup" method="POST">
  <input type="email" name="email" required>
  <div class="infopeak-captcha" data-sitekey="YOUR_SITEKEY"></div>
  <button type="submit">Sign up</button>
</form>
<script src="https://captcha.infopeak.io/infopeak-captcha.js" defer></script>

Verify the token when the form is submitted:

use InfoPeak\Captcha\Client;

$captcha = new Client('YOUR_SITEKEY', 'YOUR_SECRET');

if (!$captcha->verify($_POST[Client::FIELD] ?? '')) {
    http_response_code(400);
    exit('Captcha verification failed');
}
// ... proceed

Need quota information too?

$result = $captcha->verifyDetailed($_POST[Client::FIELD] ?? '');
$result->valid;     // bool - token genuine and unused
$result->overLimit; // bool - sitekey over its monthly quota

Verification fails closed: network errors and non-200 responses return valid = false.

Retrying a rejected submission

Tokens are single-use. If you reject a submission and leave the visitor on the same page - an AJAX form, a wrong password, a validation error - the token already in the form is spent, and the next attempt fails on the captcha instead of on the real problem. Ask the widget for a fresh one:

window.infopeakCaptcha.reset();

// Or one specific widget, by element or CSS selector.
window.infopeakCaptcha.reset('#signup-captcha');

reset() clears the hidden field and solves again immediately, and returns the number of widgets it reset. Plain form posts do not need this - the page reload builds a new widget anyway.

Testing

Public test credentials that work on any domain and never count against a quota (never use in production):

sitekey: ipk_test_sitekey
secret:  ipk_test_secret

Links

License

MIT