{"id":321800,"date":"2026-06-04T10:39:46","date_gmt":"2026-06-04T10:39:46","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/captchaapi-eu-proof-of-work-captcha\/"},"modified":"2026-06-04T10:39:25","modified_gmt":"2026-06-04T10:39:25","slug":"captchaapi","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/captchaapi\/","author":23510521,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.1","stable_tag":"1.0.1","tested":"7.0","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"captchaapi.eu Proof-of-Work CAPTCHA","header_author":"captchaapi.eu","header_description":"Privacy-first proof-of-work CAPTCHA. Protects the login, registration, lost-password, and comment forms, plus Contact Form 7. EU-hosted, no cookies, no tracking.","assets_banners_color":"0a3e35","last_updated":"2026-06-04 10:39:25","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/captchaapi.eu\/docs","header_author_uri":"https:\/\/captchaapi.eu","rating":0,"author_block_rating":0,"active_installs":0,"downloads":33,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.1":{"tag":"1.0.1","author":"rajtik","date":"2026-06-04 10:39:25"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3560754,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3560754,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3560769,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3560769,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3560769,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.1"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[109,362,107,602,599],"plugin_category":[38,44,54],"plugin_contributors":[265798],"plugin_business_model":[],"class_list":["post-321800","plugin","type-plugin","status-publish","hentry","plugin_tags-antispam","plugin_tags-captcha","plugin_tags-comments","plugin_tags-login","plugin_tags-spam","plugin_category-authentication","plugin_category-discussion-and-community","plugin_category-security-and-spam-protection","plugin_contributors-rajtik","plugin_committers-rajtik"],"banners":{"banner":"https:\/\/ps.w.org\/captchaapi\/assets\/banner-772x250.png?rev=3560769","banner_2x":"https:\/\/ps.w.org\/captchaapi\/assets\/banner-1544x500.png?rev=3560769","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/captchaapi\/assets\/icon.svg?rev=3560769","icon":"https:\/\/ps.w.org\/captchaapi\/assets\/icon.svg?rev=3560769","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>captchaapi.eu stops form spam without making your visitors click traffic lights. The work happens in the background: the visitor's browser solves a small proof-of-work puzzle while they fill in the form, and a signed token rides along with the submission. There is nothing to solve and nothing to see.<\/p>\n\n<p>Your server checks that token locally with your secret key. No request is sent back to captchaapi.eu when a form is submitted, so the check adds no network latency and keeps working even if our service is briefly unreachable.<\/p>\n\n<p>The service runs on hardware in the EU (Nuremberg, Germany). It sets no cookies and writes no per-visitor record to a database; the visitor's IP address is used only transiently for rate limiting and abuse detection.<\/p>\n\n<h4>What it protects<\/h4>\n\n<ul>\n<li>Login (wp-login.php)<\/li>\n<li>Registration<\/li>\n<li>Lost password<\/li>\n<li>Comments<\/li>\n<li>Contact Form 7<\/li>\n<\/ul>\n\n<p>Each surface can be turned on or off from the settings screen. Contact Form 7 support appears only when that plugin is active.<\/p>\n\n<h4>How it works<\/h4>\n\n<ol>\n<li>The widget loads on the pages with a protected form and solves a proof-of-work puzzle in a Web Worker.<\/li>\n<li>On submit, it attaches a short-lived, signed attestation to the form.<\/li>\n<li>The plugin verifies the attestation with your secret key (an HMAC check) and rejects the submission if it is missing, forged, expired, or reused.<\/li>\n<\/ol>\n\n<p>Reuse is blocked with a single-use record per token. If your site has a persistent object cache (Redis or Memcached), that record lives there. Otherwise the plugin keeps a small table and clears expired rows on a schedule.<\/p>\n\n<h4>You need an account<\/h4>\n\n<p>This plugin connects to the captchaapi.eu service. Create a project at https:\/\/captchaapi.eu to get a site key and a secret key. A free tier is available.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to captchaapi.eu, a third-party CAPTCHA service, to protect your forms from spam. It is required for the plugin to function.<\/p>\n\n<p>On any public page that contains a protected form, the plugin loads the service's widget script (captcha.js) from your configured captchaapi.eu endpoint. The visitor's browser then communicates with the captchaapi.eu API to perform a proof-of-work challenge and obtain a signed attestation that is attached to the form on submit. This happens for every visitor who loads a protected form.<\/p>\n\n<p>To issue and validate an attestation the service receives your public site key, the proof-of-work result, and - as with any HTTP request - the visitor's IP address. The IP address is used for rate limiting and abuse\/bot detection (including a coarse, IP-derived country) and is processed transiently: a hashed form and aggregate counters are held briefly in a cache. No raw IP address and no per-visitor record are written to a database. The service sets no cookies. Data is processed on servers in the EU (Nuremberg, Germany).<\/p>\n\n<p>Verification of the attestation on submit is performed locally on your server with your secret key; no request is sent back to captchaapi.eu at that point.<\/p>\n\n<ul>\n<li>Service provider: captchaapi.eu<\/li>\n<li>Terms of Service: https:\/\/captchaapi.eu\/legal\/terms<\/li>\n<li>Privacy Policy: https:\/\/captchaapi.eu\/legal\/privacy<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>wp-content\/plugins\/captchaapi<\/code>, or install it from the Plugins screen.<\/li>\n<li>Activate it.<\/li>\n<li>Open Settings -&gt; captchaapi.eu.<\/li>\n<li>Enter your site key and secret key from your project dashboard.<\/li>\n<li>Choose which forms to protect and save.<\/li>\n<\/ol>\n\n<p>For a stricter setup, keep the secret key out of the database by defining it in <code>wp-config.php<\/code>:<\/p>\n\n<pre><code>define( 'CAPTCHAAPI_SECRET_KEYS', 'your_secret_key' );\n<\/code><\/pre>\n\n<p>During a key rotation, list the current and the new key together, separated by a comma:<\/p>\n\n<pre><code>define( 'CAPTCHAAPI_SECRET_KEYS', 'current_key,new_key' );\n<\/code><\/pre>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20my%20visitors%20have%20to%20solve%20anything%3F\"><h3>Do my visitors have to solve anything?<\/h3><\/dt>\n<dd><p>No. There is no image challenge and no checkbox. The proof-of-work runs in the browser while the form is being filled in.<\/p><\/dd>\n<dt id=\"does%20form%20submission%20slow%20down%3F\"><h3>Does form submission slow down?<\/h3><\/dt>\n<dd><p>The verification is a local HMAC check, so it adds no network round trip on submit. The browser does its proof-of-work in the background before the submit, usually in well under a second.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20captchaapi.eu%20is%20unreachable%3F\"><h3>What happens if captchaapi.eu is unreachable?<\/h3><\/dt>\n<dd><p>The widget will not produce an attestation, so a protected form will not submit. The plugin fails closed by design: a submission without a valid attestation is rejected rather than waved through.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20contact%20form%207%3F\"><h3>Does it work with Contact Form 7?<\/h3><\/dt>\n<dd><p>Yes. Enable Contact Form 7 in the settings. The plugin acquires an attestation before Contact Form 7 sends the form and verifies it on the server.<\/p><\/dd>\n<dt id=\"do%20you%20set%20cookies%20or%20track%20visitors%3F\"><h3>Do you set cookies or track visitors?<\/h3><\/dt>\n<dd><p>No cookies, no profiling, and no third-party requests beyond the widget talking to the API. The visitor's IP address is used only transiently for rate limiting and abuse\/bot detection; it is not stored in a database and is not used to build a visitor profile.<\/p><\/dd>\n<dt id=\"where%20is%20the%20data%20processed%3F\"><h3>Where is the data processed?<\/h3><\/dt>\n<dd><p>On servers in the EU.<\/p><\/dd>\n<dt id=\"which%20login%20forms%20are%20covered%3F\"><h3>Which login forms are covered?<\/h3><\/dt>\n<dd><p>The standard WordPress login form at wp-login.php. WooCommerce and other custom login forms are not covered in this version.<\/p><\/dd>\n<dt id=\"does%20it%20protect%20xml-rpc%3F\"><h3>Does it protect XML-RPC?<\/h3><\/dt>\n<dd><p>No. The check is a browser-side proof of work, so it only runs on real form submissions in a browser. XML-RPC and the REST API are not browsers, so they are left untouched and a captcha cannot gate them. If you do not use XML-RPC, disabling it separately closes that brute-force surface.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on multisite?<\/h3><\/dt>\n<dd><p>This version targets single-site installs. Network signup through wp-signup.php is not covered yet.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Compatibility and Plugin Check fixes for the WordPress.org directory: updated \"Tested up to\", aligned the plugin name with the readme, versioned the enqueued widget script, prefixed an uninstall global, and dropped the redundant load_plugin_textdomain() call.<\/li>\n<li>Documented the captchaapi.eu external service in the readme, including the data sent and links to the Terms of Service and Privacy Policy.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release. Protects login, registration, lost password, comments, and Contact Form 7.<\/li>\n<\/ul>","raw_excerpt":"Proof-of-work CAPTCHA with no puzzles and no cookies. Protects login, registration, comments, and Contact Form 7; IP used only for abuse checks.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/321800","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=321800"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/rajtik"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=321800"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=321800"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=321800"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=321800"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=321800"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=321800"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}