Risk scoring, thresholds, and the REST gateway
Last updated July 10, 2026
Risk scoring: who gets challenged and why
The heart of SWPL Captcha Pro is that protection is risk-scored, not all-or-nothing. Every protected submission is scored from server-side signals, and only that score decides what happens:
- Below the Challenge threshold (default 30): the request is allowed silently. The CAPTCHA provider is never even contacted, so the visitor sees nothing at all.
- At or above the Challenge threshold: the request must pass a provider challenge (your Turnstile, reCAPTCHA, or hCaptcha). Passing lets it through; failing is treated as suspicious.
- At or above the Block threshold (default 70): the request is blocked outright, with no challenge offered – it looks too risky to bother.
What goes into the score
Each signal carries risk points; the points are summed and held between 0 and 100:
- A filled honeypot field – a hidden trap real visitors never see or touch: +40.
- Suspicious form timing – submitted in under a second, or on a page left open for over an hour: up to +40.
- A missing or bot-like browser signature – no User-Agent: +30; a known bot User-Agent: +20; no Accept-Language: +10; an off-site referer: +5.
- High request volume from one IP in a short window – low, medium, or high velocity: +15, +30, or +50.
- The provider verdict, once a challenge runs – a failed challenge adds +40; a passed one subtracts 20.
- Being a logged-in WordPress user subtracts 20 – a registered customer is far less likely to be a bot.
A normal shopper accumulates little or no risk and stays below the Challenge threshold; a logged-in customer is lowered further still – which is why paying customers pass silently even on protected checkout and payment forms.
Tuning the thresholds
- Challenge threshold (0-100, default 30). Lower is stricter: more visitors are challenged. Too low and real visitors see challenges more often; too high and more suspicious requests slip through unchallenged.
- Block threshold (0-100, default 70, normally above the Challenge threshold). Too low risks blocking real visitors who happened to score high; too high means even very suspicious requests only get a challenge rather than a block.
Adjust the thresholds first and watch the Analytics tab. Only reach for the signal weights (advanced) when you want a specific signal to count for more or less – each weight ranges from -100 to 100, and a negative weight makes a signal lower the score. If tuning goes wrong, Tools > Reset restores the defaults.
The REST API Gateway (experimental)
Beyond per-form protection, the Gateway guards whole WordPress REST API routes at the request level. It stays off until you list routes to protect – an exact route, a /prefix/* wildcard, or a route pattern – and the tab lists your site’s registered routes so you can copy real paths. Each protected route is rate-limited per IP over a 60-second window (default 60 requests per minute; over the limit returns HTTP 429 with a Retry-After). Requests under the limit get a signal-only risk score – browser fingerprint plus the IP’s request rate, since an API has no CAPTCHA widget to fall back on – and a request scoring at or above the Gateway block threshold (default 80, set on the Signals tab) is rejected with HTTP 403. Administrators and WP-Cron are never gated.
Because this acts on real API traffic, start with a single route and a generous rate limit, watch the Analytics tab for what gets gated, then tighten gradually. A wrong or too-broad entry can block legitimate API traffic.
Headless front ends
If your storefront runs as a separate app (Next.js, a mobile app), the REST endpoints – config, verify, and report under /wp-json/swpl-captcha-pro/v1/ – score requests with the same engine. Issue API keys on the REST tab (sent in the X-SWPL-Captcha-Key header; stored hashed, so copy a key when you create it – it is never shown again) and list your front end’s exact origins for CORS, one per line; empty means same-origin only. A standard WordPress or WooCommerce theme needs nothing here.
Getting the visitor’s real IP right
Velocity scoring is per IP, so the IP must be real. Behind a proxy or CDN you control (Cloudflare, for example), enable Trusted proxy and pick the forwarded-IP header your proxy actually sends: X-Forwarded-For, CF-Connecting-IP, or X-Real-IP. Never enable it without such a proxy – a visitor could then spoof their IP to dodge the velocity limits or frame another address.
Housekeeping
The Tools tab exports all settings as JSON (secrets redacted unless you deliberately opt in), imports a previously exported file (redacted secrets keep the stored values rather than wiping them), and resets everything to defaults behind an explicit confirmation. The Data retention setting controls how many days of Analytics event-log rows are kept before the daily prune.