Skip to main content

Advanced

The ALTCHA WordPress plugin automatically protects your site right after installation, with no extra setup required. This page covers advanced topics and custom integrations for developers and power users who want more control.

Shortcode

Add the widget manually anywhere shortcodes are supported:

[altcha]

The shortcode accepts attributes based on the ALTCHA Widget configuration options:

[altcha floating auto="onload"]

Obfuscation

Starting in v2.1.0, the plugin can obfuscate sensitive data — like email addresses and phone numbers — so it's hidden from bots but still usable by real visitors.

[obfuscate email="test@example.com" label="Click to reveal"]

Supported attributes:

AttributeDescription
emailEmail address, automatically prefixed with mailto:.
telPhone number, automatically prefixed with tel:.
textArbitrary text to obfuscate.
labelOptional placeholder text (defaults to "Click here").
classOptional CSS class names.
obfuscatedPre-generated, Base64-encoded obfuscated data, for performance.

At least one of email, tel, or text is required.

Custom handlers

For custom form handlers, verify a payload directly using the AltchaPlugin class:

$altcha = AltchaPlugin::$instance;
$params = array();
$verified = $altcha->verify($payload, $params);
  • $payload — the base64-encoded ALTCHA payload.
  • $params — populated automatically with additional parameters.

When using ALTCHA Sentinel, the resolved verification data is also available via $params["verification_data"], or as a parsed associative array through $altcha->verification_data.

Hooks

Actions

altcha_verify_result

do_action("altcha_verify_result", $verified);

Fires after a verification attempt. $verified (boolean) indicates whether it succeeded.

Filters

altcha_get_complexity

apply_filters("altcha_get_complexity", $result);

Overrides the challenge's min/max complexity. Returns an array with max and min keys.

altcha_get_challenge_options

apply_filters("altcha_get_challenge_options", $options);

Overrides the proof-of-work challenge options (CreateChallengeOptions from the PHP library).

altcha_get_challenge_url

apply_filters("altcha_get_challenge_url", $challenge_url);

Overrides the widget's challenge URL.

altcha_get_ip_address

apply_filters("altcha_get_ip_address", $ip);

Overrides the resolved visitor IP address.

altcha_get_ip_country

apply_filters("altcha_get_ip_country", null, $ip);

Overrides the detected country code. By default, get_ip_country returns null, since no IP-resolution mechanism is bundled with the plugin — use this filter to plug in your own geolocation logic or another plugin's API.

altcha_get_settings

apply_filters("altcha_get_settings", $settings);

Overrides the plugin's settings parameters.

altcha_get_widget_attrs

apply_filters("altcha_get_widget_attrs", $attrs);

Overrides the widget's HTML attributes.

altcha_get_widget_html

apply_filters("altcha_get_widget_html", $html, $attrs, $wrap);

Overrides the widget's rendered HTML. $html (string), $attrs (array), $wrap (boolean).

altcha_inject

apply_filters("altcha_inject", $inject, $bypass);

Returning false prevents the ALTCHA scripts from being added to the page. $inject (bool), $bypass (bool — true if the current user/IP/cookie already bypasses verification). See Controlling where scripts are injected below for a full example.

altcha_intercept

apply_filters("altcha_intercept", $intercept, $payload_data, $params);

Returning false disables interception, so verification isn't required for that request. $intercept (boolean), $payload_data (array), $params (array).

Plugin integrations

Thanks to the request interceptor, ALTCHA works automatically with most form plugins — no setup required. The widget displays as an overlay, or stays fully invisible in the background, depending on your configuration.

Tested plugins:

  • CoBlocks
  • Contact Form 7
  • Divi
  • Elementor Pro
  • EventPrime
  • Everest Forms
  • Fluent Forms
  • Formidable Forms
  • Forminator
  • Gravity Forms
  • HTML Forms
  • Kali Forms
  • MailPoet
  • Newsletter
  • Noptin
  • Ninja Forms
  • Sure Forms
  • WooCommerce
  • wpDiscuz
  • WPForms
  • WP-Members
  • User Registration
  • WordPress Comments
  • WordPress Login, Register, and Password Reset

If a plugin isn't recognized automatically, see Enabling ALTCHA for certain plugins below.

Country detection

The plugin determines a visitor's country from their timezone, as reported during verification. This provides reliable, privacy-friendly geolocation without depending on any IP-address resolution service.

Country is used for event logging and for firewall request blocking. For more precise geolocation, use the altcha_get_ip_country filter to plug in your own IP-based resolution logic.

Cookies and GDPR

The plugin uses only strictly necessary, first-party cookies required for the security mechanisms to work. No personally identifiable information (PII) is stored or processed through these cookies — consistent with the legitimate-interest basis under Article 6(1)(f) GDPR (security, integrity, and reliable operation).

Essential security cookie:

  • altcha — a single-use, transient functional cookie for validating form submissions and preventing spam. Contains no personal data.

Temporary protection cookies (Under Attack Mode only):

  • altcha_under_attack — session-based access management during malicious activity.
  • altcha_under_attack_expires — records the expiration timestamp.
  • altcha_under_attack_ttl — records the cookie's lifespan (time-to-live).
  • altcha_under_attack_tz — stores the visitor's timezone, for low-precision country detection.

All of these cookies are:

  • First-party, stored only on the visitor's device by your site's domain.
  • Strictly necessary for the site's security and operation.
  • Temporary, expiring automatically once their purpose is fulfilled.
  • Free of any personal or behavioral data.
  • Exempt from consent requirements under Article 5(3) of the ePrivacy Directive (Directive 2002/58/EC).

API caching

The plugin fetches challenges from:

/wp-json/altcha/v1/challenge

This endpoint must be excluded from caching by any CDN or caching plugin — it must return a fresh challenge on every request. Some hosting providers strip or ignore cookies by default; make sure the altcha cookie is excluded from caching too.

Under Attack Mode with a CDN

Most CDN providers already offer DDoS protection or rate limiting at the edge, which makes the plugin's Under Attack Mode generally unnecessary on top of that.

WP Engine: exclude these cookies from caching:

  • altcha_under_attack
  • altcha_under_attack_tz

Note that excluding these cookies causes WP Engine to bypass caching entirely for affected requests — for that reason, Under Attack Mode is not recommended on WP Engine.

Other providers: most CDNs and proxies that follow standard caching behavior and respect Cache-Control headers need no additional configuration.

How To

Enabling ALTCHA for certain plugins

If a plugin isn't in the tested list above, you can still protect its forms by adding its AJAX paths or actions in Settings:

  • REST API endpoints — add the specific path (e.g. /wp-json/some-plugin/submit) to the Paths setting, or use a wildcard (e.g. /wp-json/some-plugin/*) to cover all of that plugin's requests.
  • admin-ajax.php requests — add the AJAX action name to the Actions setting (e.g. action_name).

Controlling where scripts are injected

By default, the widget scripts load on every page. To reduce overhead, you can limit injection to only the pages that need protection, using either approach:

Option 1 — Paths setting

Add specific paths to inject on, e.g. /contact and /shop/*. Remove the default * wildcard first, or the scripts will keep loading everywhere.

Option 2 — the altcha_inject filter

Use the altcha_inject filter for programmatic control — for example, injecting only on a contact page, a shop section, and the WordPress login page when login protection is enabled:

add_filter('altcha_inject', function ($inject, $bypass) {
    if ($bypass) {
        return $inject;
    }

    $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

    if ($path === '/contact' || str_starts_with($path, '/shop/')) {
        return true;
    }

    if (str_contains($path, 'wp-login.php')) {
        return true;
    }

    return false;
}, 10, 2);

Next steps

  • Troubleshooting — diagnose issues with verification, caching, or specific plugins.
  • Releases — version history and changelog.

Start typing to search...

Navigate Select