Title: SpamAnvil – AI Anti-Spam &amp; Comment Spam Protection
Author: Alexandre Amato
Published: <strong>Hút 14, 2026</strong>
Last modified: Miyzan 27, 2026

---

Search plugins

![](https://ps.w.org/spamanvil/assets/banner-772x250.png?rev=3639366)

![](https://ps.w.org/spamanvil/assets/icon-256x256.png?rev=3639366)

# SpamAnvil – AI Anti-Spam & Comment Spam Protection

 By [Alexandre Amato](https://profiles.wordpress.org/aamato/)

[Download](https://downloads.wordpress.org/plugin/spamanvil.1.20.1.zip)

 * [Details](https://kaa.wordpress.org/plugins/spamanvil/#description)
 * [Reviews](https://kaa.wordpress.org/plugins/spamanvil/#reviews)
 *  [Installation](https://kaa.wordpress.org/plugins/spamanvil/#installation)
 * [Development](https://kaa.wordpress.org/plugins/spamanvil/#developers)

 [Support](https://wordpress.org/support/plugin/spamanvil/)

## Description

**SpamAnvil is a free, open-source WordPress anti-spam plugin — and a genuine Akismet
alternative — that uses artificial intelligence to block comment spam.** Unlike 
Akismet (which requires a paid plan for commercial sites) or simple keyword-based
filters, SpamAnvil leverages large language models (LLMs) to actually _understand_
your comments and detect even the most sophisticated spam. It layers a honeypot,
a time trap and per-IP rate limiting in front of the AI, so obvious bots are blocked
for free.

Traditional spam filters rely on static word lists and link counting. Spammers have
evolved. **SpamAnvil fights back with AI that understands context, intent, and language
patterns** – catching spam that looks legitimate and approving real comments that
others would flag.

#### Why SpamAnvil?

 * **Set up in about a minute** – Activation opens a wizard that asks for one API
   key and verifies it before saving. Nothing is stored unless the test passes.
 * **100% Free** – No premium tier, no subscription, no hidden costs. Bring your
   own API key (free options available).
 * **Smarter Than Rules** – AI understands context. A comment about “buying a new
   home” won’t be flagged just because it contains “buy”.
 * **Defense in Depth** – Honeypot, time trap, per-IP rate limit and heuristics 
   block obvious bots for free, so the AI is only spent on the subtle cases.
 * **Open Mode** – Because the filtering is invisible and automatic, you can drop
   the usual barriers (name/email, login, moderation) and get more real comments–
   even anonymous ones – without opening the door to spam.
 * **Works With Free AI Models** – Use OpenRouter’s free models for $0 cost, or 
   connect premium models for maximum accuracy.
 * **Privacy-First** – Your data stays between you and your chosen AI provider. 
   IP addresses are stored as salted, keyed hashes (HMAC-SHA-256), not recoverable
   without your site’s secret. GDPR/LGPD compliant by design.
 * **No Cloud Lock-in** – Choose from 6+ AI providers. Switch anytime. Your anti-
   spam, your rules.

#### Supported AI Providers

 * **OpenAI** (GPT-4o-mini, GPT-4o, etc.)
 * **Anthropic Claude** (Claude Sonnet, Haiku, etc.)
 * **Google Gemini** (Gemini 2.0 Flash, Pro, etc.)
 * **OpenRouter** (100+ models, including FREE ones)
 * **Featherless.ai** (Open-source models)
 * **Any OpenAI-compatible API** (LM Studio, Ollama via proxy, vLLM, etc.)

#### A Swiss-Army-Knife of Defenses

SpamAnvil layers several spam defenses so cheap, invisible filters catch obvious
bots for free and the AI only handles the subtle cases. Every layer is optional 
and runs before any paid API call:

 * **Honeypot** – A hidden field bots fill but humans never see. Instant, free block.
 * **Time trap** – Comments submitted faster than a human could type are flagged.
   Tamper-proof (signed) and fails open, so it never blocks a real visitor.
 * **Per-IP rate limit** – Throttles comment floods from a single IP before they
   even reach the database.
 * **Heuristics engine** – Regex/statistical pre-analysis (URLs, spam words, gambling/
   SEO author names, language mismatch, prompt-injection patterns) that auto-spams
   the obvious cases with no API call.
 * **AI verdict** – An LLM scores the rest 0-100 in context.

#### Key Features

 * **AI-Powered Spam Detection** – Each comment is analyzed by an LLM that scores
   it 0-100 for spam probability. Works with reasoning models (their thinking is
   parsed correctly).
 * **Layered Bot Defense** – Honeypot, time trap and per-IP rate limiting block 
   obvious bots for free, before any AI call.
 * **Model Picker** – Browse and search each provider’s live model list right from
   the settings page (OpenAI, OpenRouter, Featherless). OpenRouter shows a “free”
   badge and context size.
 * **“Open Mode”** – One toggle removes WordPress comment friction (no required 
   name/email, no login, no moderation hold) so leaving a real, even anonymous, 
   comment is effortless. Comments appear instantly and spam is removed in the background.
 * **Verdict Cache** – Identical repeated spam reuses a recent AI verdict instead
   of calling the API again, cutting cost during floods.
 * **Intelligent Heuristics Engine** – Pre-analyzes comments to catch obvious spam
   without API calls.
 * **Async Background Processing** – Comments are queued and processed via WP-Cron
   so your site stays fast.
 * **Smart IP Blocking** – Automatically blocks repeat offenders with escalating
   ban durations (24h, 48h, 96h… capped at 30 days).
 * **Automatic Retry with Backoff** – Failed API calls retry with exponential delays;
   a real “Test Connection” verifies actual classification, not just the HTTP status.
 * **Encrypted API Key Storage** – Authenticated AES-256-GCM encryption, or wp-config.
   php constants for maximum security.
 * **Statistics Dashboard & Logs** – Track spam caught by each layer, API usage 
   and errors, with the AI’s reasoning for every comment. An admin warning surfaces
   silent failures (no provider, or a backlog of failed items).
 * **Customizable AI Prompts, Fallback Providers, Prompt-Injection Defense, Configurable
   Threshold, Moderator Bypass.**

#### How It Works

 1. A visitor submits a comment.
 2. **Rate limit** – too many comments from this IP too fast? Throttled with an HTTP
    429 (before anything is stored).
 3. **IP block** – is the IP already banned for repeat spam? Blocked.
 4. **Form traps** – was the hidden honeypot filled, or the comment submitted implausibly
    fast? Marked as spam instantly, no API call.
 5. **Heuristics** – a quick regex/statistical pre-analysis; obvious spam is auto-marked
    with no API call.
 6. Otherwise the comment is queued for AI analysis (or processed immediately in sync
    mode). Identical repeated content reuses a cached verdict.
 7. The AI analyzes the comment in context (post title, author info, heuristic data)
    and returns a spam score.
 8. Comments above your threshold are marked spam; clean comments are auto-approved.
    Repeat-offender IPs are escalated.

With **Open Mode** on, comments publish instantly and any spam is removed in the
background instead of being held for moderation.

#### Use Cases

 * **Blogs** receiving hundreds of spam comments per day
 * **WooCommerce stores** where comment spam affects SEO and credibility
 * **Membership sites** that need to protect community discussions
 * **Multilingual sites** – AI understands comments in any language, unlike keyword-
   based filters
 * **High-traffic sites** – Async processing handles any volume without slowing 
   down your site
 * **Sites tired of Akismet** – Free alternative with no cloud dependency and full
   data control

#### Security

SpamAnvil follows WordPress security best practices throughout:

 * Authenticated AES-256-GCM encrypted API key storage
 * wp-config.php constant support for API keys (never touch the database)
 * Configurable trusted IP header (default REMOTE_ADDR) so a forged X-Forwarded-
   For cannot bypass IP blocking or rate limiting
 * Nonce verification on all forms and AJAX requests
 * Capability checks on all admin actions
 * Prepared SQL statements on every database query
 * Output escaping on all rendered content
 * Prompt injection defense: boundary tags around the comment body AND commenter
   metadata, system prompt hardening, heuristic injection detection (body and author
   fields), strict JSON validation, deterministic settings

#### Languages

 * English (default)
 * Translation-ready (.pot file included)

#### Third-Party Services

SpamAnvil sends comment data (content, author name, email, and URL) to external 
AI services for spam analysis. The specific service used depends on your configuration.
No data is sent until you configure and enable a provider.

 * **OpenAI** — [https://openai.com](https://openai.com) — [Terms of Use](https://openai.com/policies/terms-of-use)—
   [Privacy Policy](https://openai.com/policies/privacy-policy)
 * **Anthropic (Claude)** — [https://www.anthropic.com](https://www.anthropic.com)—
   [Terms of Service](https://www.anthropic.com/policies#terms) — [Privacy Policy](https://www.anthropic.com/policies#privacy)
 * **Google Gemini** — [https://ai.google.dev](https://ai.google.dev) — [Terms of Service](https://ai.google.dev/gemini-api/terms)—
   [Privacy Policy](https://policies.google.com/privacy)
 * **OpenRouter** — [https://openrouter.ai](https://openrouter.ai) — [Terms of Service](https://openrouter.ai/terms)—
   [Privacy Policy](https://openrouter.ai/privacy)
 * **Featherless.ai** — [https://featherless.ai](https://featherless.ai/) — [Terms of Service](https://featherless.ai/terms)—
   [Privacy Policy](https://featherless.ai/privacy)

When using the “Generic OpenAI-Compatible” option, data is sent to the URL you configure.
You are responsible for ensuring compliance with the privacy policies of your chosen
service.

## Screenshots

[⌊First-run setup - One API key, tested before it is saved. The free option costs
nothing⌉⌊First-run setup - One API key, tested before it is saved. The free option
costs nothing⌉[

First-run setup – One API key, tested before it is saved. The free option costs 
nothing

[⌊Statistics dashboard - All-time spam blocked, 30-day counters and daily activity⌉⌊
Statistics dashboard - All-time spam blocked, 30-day counters and daily activity⌉[

Statistics dashboard – All-time spam blocked, 30-day counters and daily activity

[⌊Evaluation logs - Full audit trail: score, heuristics, provider, model, the AI's
reason and response time⌉⌊Evaluation logs - Full audit trail: score, heuristics,
provider, model, the AI's reason and response time⌉[

Evaluation logs – Full audit trail: score, heuristics, provider, model, the AI’s
reason and response time

[⌊General settings - Enable/disable, processing mode, spam threshold, queue status⌉⌊
General settings - Enable/disable, processing mode, spam threshold, queue status⌉[

General settings – Enable/disable, processing mode, spam threshold, queue status

[⌊Providers tab - Chain several AI providers with per-provider models and Test Connection⌉⌊
Providers tab - Chain several AI providers with per-provider models and Test Connection⌉[

Providers tab – Chain several AI providers with per-provider models and Test Connection

[⌊Prompt tab - Editable system and user prompts, with the prompt-injection defense
built in⌉⌊Prompt tab - Editable system and user prompts, with the prompt-injection
defense built in⌉[

Prompt tab – Editable system and user prompts, with the prompt-injection defense
built in

[⌊IP Management - Visitor IP source, rate limiting and blocked IPs with escalation
levels⌉⌊IP Management - Visitor IP source, rate limiting and blocked IPs with escalation
levels⌉[

IP Management – Visitor IP source, rate limiting and blocked IPs with escalation
levels

[⌊Smart email notifications - No more one email per spam attempt: get notified only
after the verdict, or a single daily digest⌉⌊Smart email notifications - No more
one email per spam attempt: get notified only after the verdict, or a single daily
digest⌉[

Smart email notifications – No more one email per spam attempt: get notified only
after the verdict, or a single daily digest

## Installation

#### Automatic Installation

 1. Go to **Plugins > Add New** in your WordPress admin
 2. Search for **SpamAnvil**
 3. Click **Install Now** and then **Activate**
 4. Activation opens the setup wizard – paste an API key and click **Test and finish**
 5. Done. Comments are analyzed from that moment on.

#### Manual Installation

 1. Download the plugin zip file
 2. Go to **Plugins > Add New > Upload Plugin**
 3. Upload the zip file and click **Install Now**
 4. Activate the plugin and follow the setup wizard

#### Getting a Free API Key

The setup wizard walks you through this, but in full:

 1. Create an account at [OpenRouter.ai](https://openrouter.ai/) and generate an API
    key
 2. Paste it into the wizard, or into the OpenRouter card under **Settings > SpamAnvil
    > Providers**
 3. The default model setting is OpenRouter’s free router chain (`openrouter/free, 
    openrouter/auto`), so free models are tried first

OpenRouter rate-limits free usage, which is plenty for a normal blog; a busy site
can add credit to raise the limits.

#### Optional: Define API keys in wp-config.php

For maximum security, define API keys as constants in your wp-config.php:

    ```
    define('SPAMANVIL_OPENAI_API_KEY', 'sk-...');
    define('SPAMANVIL_OPENROUTER_API_KEY', 'sk-or-...');
    define('SPAMANVIL_ANTHROPIC_API_KEY', 'sk-ant-...');
    define('SPAMANVIL_GEMINI_API_KEY', '...');
    define('SPAMANVIL_FEATHERLESS_API_KEY', '...');
    ```

When keys are defined in wp-config.php, they are never stored in the database at
all.

## FAQ

### Is SpamAnvil really free?

Yes, 100% free and open source. There is no premium version. You only need an API
key from an AI provider, and free options are available (e.g., OpenRouter with free
Llama models).

### How is SpamAnvil different from Akismet?

Akismet uses a centralized cloud service owned by Automattic. It requires a paid
subscription for commercial sites, and all your comments are sent to Akismet’s servers.
SpamAnvil lets you choose your own AI provider, works with free models, keeps you
in control of your data, and uses true AI understanding instead of statistical pattern
matching.

### How is SpamAnvil different from Antispam Bee?

Antispam Bee uses traditional techniques like honeypot fields, country blocking,
and regex rules. These work for basic spam but miss sophisticated attacks. SpamAnvil
adds AI analysis that actually reads and understands comments in context, catching
spam that looks legitimate to keyword-based systems.

### Which AI provider should I use?

**For free usage:** OpenRouter with the free Llama 3.1 8B model works surprisingly
well for spam detection.
 **For best accuracy:** OpenAI GPT-4o-mini offers the best
quality-to-price ratio. **For privacy:** Google Gemini or a self-hosted model via
the Generic OpenAI-compatible option. **For maximum reliability:** Configure a primary
+ fallback provider so spam checking never stops.

### Does this slow down my website?

No. In the default async mode, comments are held as “pending” and processed in the
background via WP-Cron every 5 minutes. Your visitors experience zero added latency.
There’s also a sync mode available if you prefer instant results.

### What happens if the AI service is down?

SpamAnvil has built-in resilience: failed requests are retried up to 3 times with
exponential backoff (1 min, 5 min, 15 min). You can also configure a fallback provider
that kicks in automatically when the primary fails.

### Is my data safe?

Comment content is sent to your chosen AI provider for analysis – this is the only
external data transmission. API keys are encrypted with authenticated AES-256-GCM
in the database (or can be defined in wp-config.php to never touch the database).
IP addresses are stored as salted, keyed hashes (HMAC-SHA-256, not reversible without
your site’s secret) and displayed masked in the admin panel.

### Does SpamAnvil work with WooCommerce?

Yes. SpamAnvil hooks into WordPress’s standard comment system, which WooCommerce
product reviews also use.

### Does it work with multilingual sites?

Yes! AI language models understand comments in virtually any language. This is a
major advantage over keyword-based spam filters that only work for English.

### Can spammers trick the AI with prompt injection?

SpamAnvil uses 6 layers of prompt injection defense: (1) comment content is wrapped
in `<comment_data>` boundary tags, (2) the system prompt explicitly instructs the
AI to ignore instructions within comments, (3) heuristic patterns detect common 
injection phrases and raise the spam score, (4) responses are validated as strict
JSON, (5) LLM temperature is set to 0 for deterministic behavior, (6) content is
truncated at 5,000 characters.

### What is Open Mode?

Open Mode is an optional toggle (Settings  General) that makes leaving a real comment
effortless. It removes WordPress’s usual friction – no required name/email (anonymous
comments allowed), no login, no first-comment moderation hold – and publishes comments
instantly, letting SpamAnvil quietly remove any spam in the background. It’s safe
to enable because the invisible defense layers (honeypot, time trap, rate limit,
heuristics, AI) still filter spam automatically. It’s applied via filters, so turning
it off restores your original settings. Tip: pair it with Sync mode if you want 
zero delay on very low-traffic sites.

### Will the honeypot or time trap block real visitors?

No. The honeypot is a hidden field only bots fill, and the time trap uses a signed
timestamp and “fails open” – if anything is missing or looks off, it never flags
the comment. Both are invisible to real visitors and, when in doubt, mark a comment
as spam (recoverable from the Spam folder) rather than hard-blocking it.

### Can I browse a provider’s models?

Yes. On the Providers tab, click “Browse models” next to the model field for OpenAI,
OpenRouter or Featherless to search that provider’s live model list and pick one.
OpenRouter models show a “free” badge and context size.

### Can I use a local/self-hosted AI model?

Yes! If you run a local model with an OpenAI-compatible API (e.g., LM Studio, Ollama
with a proxy, vLLM, Text Generation WebUI), you can connect it using the “Generic
OpenAI-Compatible” provider option with your local URL.

### Who developed SpamAnvil?

SpamAnvil was created by [Dr. Alexandre Amato](https://vascular.pro), a vascular
surgeon and software developer based in Brazil. When he’s not in the operating room,
he builds open-source tools and medical education resources such as [Enciclopédia Médica](https://enciclopedia.med.br).

### What WordPress versions are supported?

SpamAnvil requires WordPress 5.8+ and PHP 7.4+.

### How can I support SpamAnvil?

SpamAnvil is 100% free and always will be. No premium tier, no “pro” upsells. If
it’s saving you time and money, you can [sponsor the project on GitHub](https://github.com/sponsors/alexandreamato).
What’s the next WordPress problem I’ll solve and make free? I’m tired of expensive
solutions for simple problems.

## Reviews

![](https://secure.gravatar.com/avatar/36f11e8b6a8c4aa86f3aaf7dfd2b0811e46f65cd0f6139ef5bcaa3c66122269f?
s=60&d=retro&r=g)

### 󠀁[Good](https://wordpress.org/support/topic/good-9136/)󠁿

 [tanvirmove](https://profiles.wordpress.org/tanvirmove/) Jawza 18, 2026 1 reply

SpamAnvil is good

 [ Read all 1 review ](https://wordpress.org/support/plugin/spamanvil/reviews/)

## Contributors & Developers

“SpamAnvil – AI Anti-Spam & Comment Spam Protection” is open source software. The
following people have contributed to this plugin.

Contributors

 *   [ Alexandre Amato ](https://profiles.wordpress.org/aamato/)

[Translate “SpamAnvil – AI Anti-Spam & Comment Spam Protection” into your language.](https://translate.wordpress.org/projects/wp-plugins/spamanvil)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/spamanvil/), check 
out the [SVN repository](https://plugins.svn.wordpress.org/spamanvil/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/spamanvil/) by [RSS](https://plugins.trac.wordpress.org/log/spamanvil/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.20.1

 * Fix: **with a slow first model, the fallback model was never tried** (introduced
   in 1.20.0). The time limit gave the first model in the list all the time the 
   run had left. When that model hung, it used up the whole budget, no time remained
   for the next model, and the next run started again from the first — so a healthy
   fallback could go unused indefinitely while the comment waited. Each call now
   leaves at least 8 seconds for every model still behind it in the list, so a hanging
   first model is cut off in time for the fallback to answer in the same run.
 * Fix: the automatic search for a replacement free model (used when a configured
   model has disappeared) listed the provider’s models with a fixed 30-second timeout,
   outside the run’s time limit. It now gets only the time that is left, minus what
   the classification call after it needs.

#### 1.20.0

 * Fix: **the background job could run far past its time limit.** It allows itself
   50 seconds per run, but only checked the clock after finishing a whole comment—
   and a single comment can go through several models, each allowed 60 seconds to
   answer. On a slow day one run could take minutes, pile up against the next one,
   or be killed by the host halfway through. Every model call is now limited to 
   the time the run has left, and a call is not started at all when fewer than 8
   seconds remain: the comment goes back to the queue untouched and is picked up
   on the next run. If some models were asked and none answered in time, it counts
   as a normal failed attempt with the usual backoff, so a model that always hangs
   cannot keep a comment cycling forever.
 * Fix: **behind a proxy or CDN, repeat offenders were counted by the proxy’s address.**
   The block check at submission uses the visitor IP from the header you chose on
   the IP tab (1.10.0), but the repeat-offender count taken after a verdict — usually
   in the background job — read the address WordPress stored, which behind a proxy
   is the proxy’s. SpamAnvil now remembers the visitor IP it resolved when the comment
   arrived and uses that same identity at every step. Sites not behind a proxy are
   unaffected and store nothing extra.
 * Fix: log and statistics retention drifted by the site’s time zone. Entries are
   written in the site’s local time, but the cleanup compared them against UTC, 
   so on a site at UTC−3 logs were removed 3 hours early (up to 14 hours in other
   zones). The cutoffs, and the date ranges of the Statistics tab, now use the site’s
   time zone.
 * Fix: the verdict cache did not notice a change of endpoint for the “Generic OpenAI-
   compatible” provider. Pointing it at another server with the same model name 
   and key kept serving the old server’s verdicts. The endpoint is now part of the
   provider fingerprint.
 * New: a warning under the Generic provider’s API URL when it uses plain `http://`
   to a server on the internet: the API key and every comment, with the commenter’s
   name and email, would travel unencrypted. Local and private-network addresses(
   a model on the same machine or LAN) are not flagged.
 * Fix: the text SpamAnvil suggests for your privacy policy said IP addresses are
   stored “only” as hashes. A partly masked form is also kept for the IP tab, and
   since this release the visitor IP resolved behind a proxy is kept with the comment.
   The text now says both.
 * Clarification of 1.19.1: a moderator’s decision is checked against the database
   right before a verdict is applied, so a change made while the AI was answering
   is respected. The check and the write are still two steps, so a moderation landing
   in the few milliseconds between them can be overwritten; the 1.19.1 notice said“
   always”, which overstated it.
 * Development: the test suite now also runs against WordPress 5.8 on PHP 7.4 — 
   the oldest versions the plugin declares support for — not only the latest WordPress.

#### 1.19.1

 * Fix: **1.19.0’s second check before applying a verdict did not work on most sites.**
   It re-read the comment’s status through WordPress’ in-request cache, which the
   background job had filled when it loaded the comment — so a moderator acting 
   in another browser tab while the model was answering was invisible to it, and
   the verdict overwrote their decision anyway. The status (and the moderation mark
   below) is now read straight from the database. The 1.19.0 test changed the comment
   inside the same request, where the cache is cleared, so it passed without proving
   anything; the new test writes the database the way a separate request does, and
   fails against the 1.19.0 code.
 * Fix: **sending a comment back to “pending” did not count as a moderator’s decision.**
   A comment the AI marked as spam, returned to pending by a moderator, could be
   picked up again by the automatic scan of pending comments and get the same verdict
   from the cache; a comment a moderator unapproved could be approved automatically.
   Now every status change a person (or another plugin) makes — approve, pending,
   spam, trash — is recorded on the comment, evicts its cached verdict and closes
   its queue entry, and the automatic paths leave that comment alone. The manual“
   Scan pending” button is how you ask for a fresh analysis. SpamAnvil’s own verdicts,
   honeypot, time trap and heuristic blocks are not recorded as moderation.
 * Fix: the verdict cache ignored which provider and model answered, so switching
   to another model kept serving the old model’s verdicts. The provider configuration
   is now part of the cache key.
 * New: **the “Privacy Notice” option now does what it says.** The checkbox (on 
   by default) was saved but nothing ever displayed it. When SpamAnvil is on and
   a provider is configured, commenters now see one line above the submit button
   saying their comment, name, email and website are sent to an external AI service
   to filter spam. Moderators, whose comments are never analyzed, do not see it.
   SpamAnvil also suggests matching text for your privacy policy under Settings  
   Privacy. Turn the option off on the General tab if your privacy policy already
   covers it.
 * Fix: uninstalling with “Delete data” on left behind the cached verdicts and per-
   comment bookkeeping; they are now removed. The daily email digest is now unscheduled
   on uninstall, and re-scheduled if its cron event goes missing.

#### 1.19.0

 * Fix: **the 1.16.0 prompt fix never reached sites that simply clicked “Update”.**
   WordPress does not run a plugin’s activation code on update, so SpamAnvil re-
   runs its migrations when it notices a new version — but it only compared the 
   database schema version, and 1.16.0 changed the default prompt without changing
   the schema. Sites that updated from 1.15.x or earlier without deactivating and
   reactivating stayed on the old prompt, the one that marked comments in another
   language, and short polite ones, as spam. Migrations now run whenever the plugin
   version changes, so this update applies the 1.16.0 prompt at last. As before,
   only unmodified default prompts are replaced; customized prompts are left alone.
   The 1.16.0 upgrade notice said this happened automatically; for those sites it
   did not.
 * Fix: “Reset to Default” on the Prompt tab restored the pre-1.16.0 prompt, from
   a copy kept in the JavaScript that was never updated. The button now uses the
   plugin’s current defaults.
 * Fix: **turning SpamAnvil off did not stop the analysis.** The switch on the General
   tab stopped new comments from being queued, but the background job kept processing
   what was already queued and kept picking up pending comments, spending API calls.
   Now the switch stops everything: the background job, the manual “Process queue”
   and “Scan pending” buttons, and Open Mode’s changes to WordPress’ comment settings.
   Queued comments wait and are processed once SpamAnvil is on again.
 * Fix: **a comment that a moderator had already handled could be overruled by the
   queue.** The queue checked only that the comment still existed, so a comment 
   sent to the trash while it waited could come back approved when its turn came.
   Now moderating a comment — approving it, marking it spam or trashing it, whether
   done by a person or another plugin — closes its queue entry without an API call.
   SpamAnvil also checks again right before applying a verdict, because a model 
   can take a minute to answer: if someone decided in the meantime, the AI’s verdict
   is written to the log and the comment is left as that person set it. In Open 
   Mode and Sync mode, where comments are published before analysis, an approved
   comment is still analyzed as before.
 * Fix: **the verdict cache could reuse a verdict for a different situation.** It
   matched only the comment text and the author’s website, so the same words on 
   another post, from another author, or after a prompt change got the old verdict
   for up to 7 days. The cache now matches only when everything the model would 
   see is identical: text, post, author name, email and website, and the prompts.
   When a moderator overturns a verdict that came from the cache, that entry is 
   deleted so the same text is not judged the same way again.
 * Change: **OpenRouter now uses free models only by default.** Since 1.13.1 the
   default was “openrouter/free, openrouter/auto”: when the free models could not
   answer — about 4 calls in 10 — the paid `openrouter/auto` stepped in. An account
   without credit was never charged, but one with credit paid for part of the analysis
   without being told, while the setup wizard said the free option “costs nothing”.
   The default is now `openrouter/free` alone; when no free model answers, the comment
   waits in the queue and is retried later. Existing sites move to the new default
   only if they were still on a chain SpamAnvil wrote itself (the old default, or
   the one the 1.17.0 wizard stored); a chain you edited is left alone. To let a
   paid model step in again, add `openrouter/auto` at the end of the model list 
   on the Providers tab.

#### 1.18.1

 * Fix: on sites with `WP_DEBUG` enabled, WordPress logged “Translation loading 
   for the spamanvil domain was triggered too early” whenever the plugin had to (
   re)schedule its cron events. Scheduling runs on `plugins_loaded` and reaches 
   the `cron_schedules` filter, where the interval’s label is translated — before
   WordPress is ready for translations. Schema check and cron scheduling now run
   on `init` instead. Verified against WordPress 7.1-RC4: the notice is gone and
   the events still schedule.
 * Fix: 1.15.0 added a second `set_transient( 'spamanvil_activation_redirect' )`
   inside the activator, which also runs on a database-version change — so a future
   schema bump would have redirected people to the settings screen out of nowhere.
   Removed; the activation hook has always set it.
 * **Correction to the 1.15.0 release notes.** They stated that the post-activation
   redirect “never actually happened” because nothing set the flag it reads. That
   was wrong: `spamanvil.php` has set that transient since 1.1.1, and the redirect
   did fire. What 1.15.0 genuinely changed was its destination — unconfigured installs
   now land on the setup wizard instead of the settings page.
 * Compatibility: WordPress 7.1 verified end to end on RC4 rather than by code review—
   activation, all admin screens, the comment form’s honeypot and signed time trap,
   an anonymous comment reaching the queue, a bot caught by the honeypot, per-IP
   rate limiting, and cron scheduling. No PHP notices, warnings or deprecations 
   from the plugin.

#### 1.18.0

 * New: **a screen to get back the comments that were flagged by mistake.** The 
   prompt rules removed in 1.16.0 had been auto-marking real readers as spam — a
   comment written in another language scored 75+, generic praise 70+. Fixing the
   rules does not bring those comments back, and WordPress deletes spam older than
   30 days on its own, so they are recoverable only for a while. Settings  SpamAnvil
   Logs now links to a review screen listing the spam-flagged comments that carry
   no link and no author website and whose score sits just above your threshold —
   the shape a wrongly flagged reader has, and the shape real spam almost never 
   has. Each row shows the AI’s own reason for flagging it, and ticking a comment
   restores and publishes it. A dismissible notice points there while there is something
   to review. Verdicts from the honeypot, time trap, rate limit and heuristics are
   never listed: those are deterministic, and were never the prompt’s doing.

#### 1.17.0

 * Fix: the setup wizard could reject a perfectly good API key, and new installs
   were left on a model that fails roughly 4 calls in 10. OpenRouter’s `openrouter/
   free` is a _router_, not a model: it picks a different free model per call, and
   part of that pool cannot do this job at all — one real run was routed to a content-
   safety classifier whose entire reply is “User Safety: safe”, which no JSON parser
   can rescue. The wizard now checks whether the configured model actually answers;
   if it does not, it asks the provider what else is free, skips the ones that cannot
   answer (safety classifiers, code, embedding, vision, speech and media models),
   and stores the first that works — keeping the router behind it as the fallback
   that never goes stale. A rejected key still fails immediately, without probing
   alternatives.
 * Fix: the automatic free-model fallback (1.9.0) took the first free model in the
   provider’s list, which today is a code model. It now applies the same filter.
 * Fix: Test Connection ran a simplified prompt, so a model could pass it and still
   fail on the ~6 KB prompt production sends. It now tests with the site’s real 
   system prompt — the false green it was introduced to prevent.

#### 1.16.0

 * **Accuracy fix: the default prompt was marking real comments as spam.** Measured
   against a labeled set on two different free models, 3 of 7 genuine comments were
   auto-spammed — every one of them because the prompt stated that “a comment in
   a different language than the site language is highly suspicious. Score 75+”.
   A detailed, on-topic Portuguese comment on an English-language site scored 78
   and 85 on the two models. That rule is gone: language is no longer a signal at
   all. Generic praise on its own (no link, no author URL, nothing else) now scores
   45-60 instead of 70+, and reaching 70 — the score that hides a comment — now 
   requires a real promotional or deceptive signal: a promoted link, monetization
   keywords, a brand-name author, an injection attempt, or an identity that does
   not add up. Spam detection did not suffer: 0 false negatives before and after,
   with spam scores higher than before.
 * Fix: reasoning models could spend the whole token budget thinking and return 
   no JSON at all (“Could not parse a score from the response”). `max_tokens` for
   OpenAI-compatible providers is now 800 instead of 400, and the prompt tells the
   model not to reason out loud. Parse failures over the same 14 evaluations: 3 
   before, 0 after.
 * Installs still running an unmodified previous default prompt are migrated automatically
   on upgrade. Customized prompts are never touched.

#### 1.15.0

 * New: **Setup wizard.** Activating SpamAnvil now opens a single screen that asks
   for one thing — an API key — with a direct link to a free OpenRouter key. It 
   classifies a sample comment to prove the key works, and saves nothing unless 
   it does. Until now, activation left you on the plugins list with a plugin that
   cannot act until a provider is configured, and the screen you eventually found
   asked you to choose between six providers before explaining any of them.
 * Fix: The all-time “Spam Comments Blocked” figure was shrinking. Daily statistics
   are pruned after 90 days and the total was summed from the surviving rows, so
   any install older than three months quietly lost a day of history every day —
   including the count that decides when the plugin asks for a review. Pruned counters
   are now banked and added back, so the number only grows. History deleted by earlier
   versions cannot be recovered.
 * Fix: Unconfigured installs are sent to the setup wizard after activation instead
   of the settings page. (Correction, added in 1.18.1: the original note here claimed
   the redirect never fired because nothing set the flag it reads. That was wrong—
   spamanvil.php has set it since 1.1.1.)
 * Also: the plugin’s own admin notices stay off the wizard screen, and the Installation
   instructions no longer name a default OpenRouter model that stopped being the
   default in 1.13.1.

#### 1.14.4

 * Maintenance: Shortened the 1.10.0 upgrade notice further. Plugin Check measures
   that field HTML-escaped, where every quote expands to six characters, so the 
   1.14.3 trim was still over the 300-character limit.

#### 1.14.3

 * Maintenance: Cleared the findings reported by the official Plugin Check tool,
   which WordPress.org is about to run against every plugin update. No behaviour
   changes — the review link now goes through the validated redirect helper, two
   safe-but-unannotated SQL statements are documented as such, and the 1.10.0 upgrade
   notice was trimmed to the 300-character limit.

#### 1.14.2

 * Compatibility: Tested with WordPress 7.1. No code changes were needed — SpamAnvil
   ships no block-editor assets, no media handling, no jQuery UI dependency and 
   no toolbar items, so none of the 7.1 editor, components or media changes affect
   it.
 * Maintenance: The build now runs the official Plugin Check tool on every push,
   so directory-compliance issues surface before a release instead of after it.

#### 1.14.1

 * Security fix: The 1.12.0 prompt-security migration (which isolates commenter 
   metadata inside a boundary) silently skipped any site where the admin had ever
   pressed Save on the Prompt tab: browsers submit textareas with CRLF line endings,
   so the unmodified default hashed differently from the plugin’s source string.
   Hash comparison and saving are now line-ending-normalized, and the migration 
   re-runs on upgrade — reaching those sites. Customized prompts are still never
   touched. (Field audit N1: 4 of 7 audited sites were affected.)
 * Fix: IP blocks created before the 1.12.0 escalation ceiling kept their multi-
   century expirations (e.g. a ban until the year 2743). A one-time migration caps
   legacy bans at the 30-day ceiling and escalation levels at 6; new escalations
   no longer grow the level beyond 6 (the duration ceiling lives there).
 * Hardening: Model fallback chains are capped at 10 entries as a sanity limit.

#### 1.14.0

 * Improvement: Fast recovery after AI outages. Comments that exhausted their retries
   during a provider outage no longer wait up to 24 hours after the provider recovers:
   any successful classification (or a green “Test Connection”) proves the AI is
   healthy again and gives parked items a fresh retry cycle within the hour. A per-
   item cap (5 fast cycles) prevents a comment that every model always fails on 
   from churning API calls forever — the daily safety net still guarantees every
   item is eventually retried, and a provider-configuration change always grants
   a full clean slate.
 * Maintenance: Completed queue rows are now purged after the log retention window(
   they previously accumulated forever). Unfinished work (failed/max-retries items)
   is never purged.

#### 1.13.2

 * Fix: The “Browse models” button icon could render as a broken image. It used 
   an emoji, which wp-admin rewrites into an image served from s.w.org — blocked
   on some networks/ad-blockers. It now uses a local WordPress dashicon (no external
   request). The review notice emoji was removed for the same reason.

#### 1.13.1

 * Improvement: The OpenRouter default model is now the router chain “openrouter/
   free, openrouter/auto” — the free-pool router is tried first and the paid auto
   router is the fallback. Unlike a hard-coded free model, OpenRouter’s routers 
   never go stale when individual models are deprecated. Installs still on an unmodified
   old default are migrated automatically; custom model choices are never touched.

#### 1.13.0

 * New: Smart email notifications (enabled by default). WordPress normally emails
   you the instant a comment is held — before SpamAnvil has evaluated it, so every
   spam attempt used to generate a “please moderate” email. SpamAnvil now holds 
   those notifications and emails only after the verdict: legitimate comments notify
   the post author once approved, spam is completely silent, and you are only asked
   to moderate when the classifier genuinely could not decide (max retries reached).
   Comments from users SpamAnvil skips (e.g. moderators) keep their normal notifications.
 * New: Daily digest mode — replace per-comment emails entirely with one daily summary(
   spam blocked, comments approved, items awaiting moderation with a link). Sent
   only on days with activity.
 * The mode is configurable under Settings  SpamAnvil  General  Email Notifications(
   Smart / Daily digest / Off).

#### 1.12.0

 * Security: Commenter metadata (author name, email, URL) is now sanitized and isolated
   inside a boundary in the LLM prompt — previously an instruction-shaped author
   _name_ could inject prompt text outside the isolation block. The prompt-injection
   heuristics now scan author fields too. Installs using the unmodified default 
   prompts are migrated automatically; customized prompts are never touched.
 * Fix: Permanent configuration errors (missing or undecryptable API key, no provider
   selected) no longer burn retry attempts, recycle hourly forever, or write one
   log row per comment per cycle. The queue now pauses on a configuration error 
   and resumes automatically the moment the provider settings change. On one audited
   production site this loop had produced 1,000,000+ identical log rows (350 MB).
 * Fix: Items stuck at max retries are re-tried when the provider configuration 
   changes (or at most once a day after a transient outage) — not on the old unconditional
   hourly loop.
 * Fix: The Anthropic provider now works with current Claude models (Sonnet 5 / 
   Opus 5): the removed `temperature` parameter is no longer sent (it caused HTTP
   400), adaptive thinking is disabled for classification calls, responses are parsed
   from the content array instead of assuming the first block is text, the `refusal`
   stop reason is handled, and `max_tokens` has proper headroom. New default model:
   claude-sonnet-5.
 * Fix: IP block escalation is now capped at 30 days. Unbounded doubling produced
   effectively permanent multi-year bans (a false positive became a life sentence)
   and could overflow the database DATETIME at high levels.
 * New: Model fallback chains — the Model field accepts several models separated
   by commas, tried in order until one answers (e.g. two free OpenRouter models,
   then a paid one). The model picker gained a “+” button to append to the chain,
   and the automatic free-model fallback no longer overwrites a hand-configured 
   list.
 * Improvement: Open Mode degrades safely — when classification is paused on a configuration
   error (or no provider is configured), comments are held for review again instead
   of being published unchecked. On the audited site, a three-week provider failure
   had left 5,000+ comments published without any classification.
 * Improvement: The health notice now warns when the queue is paused (with the exact
   reason), and when comments are waiting but WP-Cron is not running (e.g. DISABLE_WP_CRON
   without a system cron).
 * Improvement: Key-decryption errors now name the provider and distinguish a corrupted
   stored value from rotated security keys (AUTH_SALT).
 * Improvement: Evaluation logs now record which model produced each error/verdict
   when trying a model chain.

#### 1.11.3

 * Fix: The “a saved API key can no longer be decrypted” notice could persist forever
   after re-entering your keys. It fired for stale keys left on providers you no
   longer use — which the Providers tab rendered as if no key were stored, with 
   nothing to clear. The notice now only considers the providers actually selected(
   primary/fallbacks), the Providers tab flags an undecryptable stored key inline
   with a visible Clear Key button, and saving or clearing a key refreshes the health
   check immediately instead of after up to 5 minutes.
 * Fix: A provider whose stored key no longer decrypts stayed listed in the Primary/
   Fallback dropdowns instead of disappearing — previously a save in that state 
   could silently reset your provider selection.

#### 1.11.2

 * Security/Privacy: Blocked-IP hashes are now salted and keyed with your site secret(
   HMAC-SHA-256) instead of a plain SHA-256. A plain hash of an IP address can be
   reversed by brute force (the IP space is small), so this makes the stored hashes
   genuinely non-reversible without your site’s key. Existing temporary blocks re-
   accrue naturally after the update.

#### 1.11.1

 * Developer: The review-request thresholds are now filterable. `spamanvil_review_min_checked`(
   default 50) and `spamanvil_review_min_age_seconds` (default 604800 = 7 days) 
   let low-traffic sites ask sooner, or others ask later. No change to default behavior.

#### 1.11.0

 * Improvement: The “leave a review” request is now a gentle, dismissible admin 
   notice that appears on any admin screen (previously it only showed on the SpamAnvil
   settings page, where most users never returned). It only appears after the plugin
   has proven itself — 50+ comments checked and at least 7 days installed — and 
   offers “Leave a review”, “Maybe later” (snoozes for two weeks), and “I already
   did / don’t ask again”. No nagging, fully dismissible, no incentives.

#### 1.10.0

 * Security: Configurable visitor-IP source. Previously the plugin trusted the left-
   most X-Forwarded-For header, which the client sends and can forge — letting a
   bot rotate a fake IP on every request to bypass IP blocking and rate limiting.
   The trusted header is now a setting under Settings  IP Management (Direct connection/
   Cloudflare CF-Connecting-IP / X-Real-IP / X-Forwarded-For right-most / Auto),
   defaulting to the un-spoofable REMOTE_ADDR. Sites behind a proxy or CDN should
   select the header their edge sets (Cloudflare  CF-Connecting-IP). The IP tab 
   shows which proxy headers your current request arrived with, to guide the choice.
 * Security: API keys are now encrypted with authenticated AES-256-GCM (AEAD) instead
   of unauthenticated AES-256-CBC. Existing keys keep working — the old format is
   still read — and re-saving a key upgrades it in place.
 * Improvement: When a saved API key can no longer be decrypted (usually because
   the site’s AUTH_SALT changed), an admin notice now says so explicitly and links
   to the Providers tab, instead of silently falling back to “no provider configured”.

#### 1.9.0

 * Feature: Automatic free-model fallback. When the configured model becomes unavailable(
   free models — especially on OpenRouter — are deprecated or removed often), SpamAnvil
   automatically finds another free model from the provider, switches to it, and
   saves the change — so spam checking keeps running with no manual intervention.
   Only triggers on “model unavailable” errors (never on auth or rate-limit issues),
   and the switch is recorded in the Logs. Toggle under Settings  Providers.

#### 1.8.0

 * Feature: “Open Mode” — maximum openness for real comments. One toggle removes
   WordPress comment friction (no required name/email, no login, no first-comment
   moderation hold) so leaving a genuine, even anonymous, comment is effortless.
   Comments appear instantly and SpamAnvil removes spam in the background; the invisible
   anti-spam layers (honeypot, time trap, rate limit, heuristics, AI) do the filtering.
   Applied via filters, so it never overwrites your stored settings and turning 
   it off restores them. Tip: pair with Sync mode for zero delay on low-traffic 
   sites.

#### 1.7.0

 * Feature: Per-IP rate limiting. Rapid repeat comments from the same IP are throttled(
   HTTP 429) before the comment is even created — stopping floods with no database,
   queue or AI cost. Configurable under Settings  IP Management (default: 5 comments
   per 60 seconds). Logged-in moderators are exempt.

#### 1.6.0

 * Feature: Time trap — a second free, pre-AI defense layer. Comments submitted 
   faster than a human could plausibly write them are marked as spam. The timestamp
   is signed (tamper-proof) and the check fails open, so it never flags a real commenter.
   Configurable threshold under Settings  General (default 3s). Note: inactive on
   sites with full-page caching.

#### 1.5.0

 * Feature: Honeypot spam trap. A hidden field is added to comment forms; automated
   bots that fill it are marked as spam instantly — before any heuristic or AI check,
   at zero cost. Enabled by default; toggle under Settings  General. Blocked bots
   are counted and appear in the Logs tab.

#### 1.4.0

 * Feature: Model picker on the Providers tab. Click “Browse models” next to OpenAI,
   OpenRouter or Featherless to search the provider’s live model list and pick one—
   no need to remember model IDs. OpenRouter models show a “free” badge and context
   size, with free models listed first and a “free only” filter.

#### 1.3.0

 * Fix (major): Comment verdicts from reasoning/chatty AI models are now parsed 
   correctly. The response reader strips `<think>...</think>` blocks, extracts the
   JSON verdict from surrounding prose, and falls back to reading the score directly—
   previously these models caused every comment to fail classification.
 * Fix: “Test Connection” now runs a real spam-classification round-trip and validates
   the reply, so a provider that returns unparseable output fails the test instead
   of showing a false success.
 * Fix: Provider failures (missing or undecryptable API key, bad config) are now
   written to the Logs tab. Previously the log stayed empty while comments silently
   failed.
 * Fix: When a stored API key can’t be decrypted (usually because the site’s security
   keys changed after a migration), the plugin now says so and asks you to re-enter
   the key, instead of the misleading “no API key configured”.
 * Enhancement: An admin warning appears when no provider is configured or comments
   are piling up unclassified, so silent failures are visible.
 * Enhancement: Larger response token budget so reasoning models have room to return
   the JSON verdict.

#### 1.2.9

 * Performance: Identical comment content now reuses a recent AI verdict instead
   of calling the LLM again — cuts API cost and latency during repeated spam floods(
   cache is on by default; keyed on comment content + author link, applied per current
   threshold).
 * Reliability: The …

## Meta

 *  Version **1.20.1**
 *  Last updated **6 saǵatlar ago**
 *  Active installations **30+**
 *  WordPress version ** 5.8 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 7.4 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/spamanvil/)
 * Tags
 * [AI](https://kaa.wordpress.org/plugins/tags/ai/)[antispam](https://kaa.wordpress.org/plugins/tags/antispam/)
   [comment spam](https://kaa.wordpress.org/plugins/tags/comment-spam/)[moderation](https://kaa.wordpress.org/plugins/tags/moderation/)
   [spam protection](https://kaa.wordpress.org/plugins/tags/spam-protection/)
 *  [Advanced View](https://kaa.wordpress.org/plugins/spamanvil/advanced/)

## Ratings

 5 out of 5 stars.

 *  [  1 5-star review     ](https://wordpress.org/support/plugin/spamanvil/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/spamanvil/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/spamanvil/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/spamanvil/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/spamanvil/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/spamanvil/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/spamanvil/reviews/)

## Contributors

 *   [ Alexandre Amato ](https://profiles.wordpress.org/aamato/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/spamanvil/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://github.com/sponsors/alexandreamato)