Skip to content

Contact form spam across client sites — an agency playbook

Every client asks why the contact form is full of spam again. A playbook for agencies: inventory the forms, standardise the basics, agree a threshold per client and put it in the retainer.

Humainbox 10 min read
In this piece
  1. What an agency portfolio actually looks like
  2. Why tuning each site's plugin does not scale
  3. Start with an inventory
  4. Standardise the cheap layers, move the judgement onto the message
  5. Dry run first, then a threshold per client
  6. Recipients, the retainer and the monthly report
  7. Where it gets hard
  8. Further reading

If you maintain websites for other businesses, you already know the email. It arrives from a different client every week and says roughly the same thing: the contact form is full of rubbish again, can you do something. Sometimes it arrives the other way round — a customer rang to ask why nobody had replied, and the enquiry was in a spam folder.

Each request is small. Across thirty or eighty sites, it is a standing cost that nobody priced in. This post is a playbook for turning it from a stream of one-off tickets into something you run once, report on and charge for properly.

What an agency portfolio actually looks like

The portfolio is rarely tidy. Most agencies inherit sites as often as they build them, so a typical book of clients spans several builders, several form plugins and several generations of anti-spam decisions.

WordPress is usually the largest share. W3Techs reports that WordPress is used by 58.8% of websites whose content management system it knows, which is 40.3% of all websites, in September 2026. Within WordPress, Contact Form 7 alone shows 10+ million active installations on its plugin page, alongside WPForms, Gravity Forms, Elementor's form widget and the rest. Then there are the Webflow, Squarespace and Wix sites, where the form lives inside the builder and your options are whatever the builder offers.

Each of those sites tends to have acquired its own anti-spam arrangement. One has reCAPTCHA, one has Cloudflare Turnstile, one has Akismet, one has a honeypot plugin somebody installed in 2019, one has all four. Contact Form 7's own plugin page lists reCAPTCHA, Akismet and Turnstile among the external services it can send submitter data to when those features are enabled — useful, but each is another integration to configure, key and keep working per site.

Every plugin is also something to update. Patchstack's State of WordPress Security in 2026 reports 11,334 new vulnerabilities found in the WordPress ecosystem in 2025, a 42% increase on 2024, with 91% in plugins and 9% in themes. The same report says 46% of vulnerabilities "did not receive a fix from the developer in time for public disclosure". Those figures cover the whole ecosystem, not anti-spam plugins in particular. But every plugin you add to fifty sites is fifty more things on the update list.

Why tuning each site's plugin does not scale

The instinct, when a client complains, is to tighten that client's form: add a CAPTCHA, turn the sensitivity up, add a required field. It works for a few weeks. Then the spam changes, or a real customer cannot get through, and the ticket comes back.

There are three reasons this does not scale.

The tools measure the wrong thing. Most form-level defences judge the visitor — is this a bot, is this IP known, did the browser behave like a person. A polished, machine-written pitch typed into the form through a real browser passes those checks, as we covered in the post on CAPTCHA. Tightening a check that the problem already passes only makes it harder for real customers.

The settings are scattered. Twenty sites means twenty admin logins, twenty sets of plugin settings and no single place to see what was blocked. When a client asks "did we miss anything last month?", the honest answer is usually that nobody can tell.

Clients need different thresholds, and per-plugin sliders do not express that. Compare two clients.

  • A private clinic. A missed patient enquiry is expensive and awkward, and messages may describe symptoms or treatment — "data concerning health" is one of the special categories in Article 9(1) of the GDPR. The UK ICO's data minimisation guidance notes: "For special category data or criminal offence data, it is particularly important to make sure you collect and retain only the minimum amount of information." That argues for fewer recipients and a loose threshold: let borderline messages through and let a person decide.
  • A B2B manufacturer. Genuine enquiries are fewer, longer and often written in a second language. The form is also a magnet for SEO offers, lead-generation pitches and machine-written "partnership" messages. A stricter threshold is sensible here, provided someone can see what was held.

The same slider position cannot be right for both, and a generic plugin setting gives you no way to explain to either client why their mail was treated the way it was.

Start with an inventory

You cannot standardise what you have not listed. Before changing anything, build one sheet for the whole portfolio.

Client Site Builder Form Recipient Current anti-spam Owner at client
Client A (clinic) clinic.example WordPress CF7 "Book a consultation" reception@ reCAPTCHA, Akismet Practice manager
Client B (manufacturer) manufacturer.example WordPress WPForms "Request a quote" sales@, md@ Honeypot Sales director
Client C (design studio) studio.example Squarespace Contact block owner's personal address Builder default Owner

A few things tend to fall out of this exercise immediately: forms nobody knew existed (an old landing page, a careers form from a campaign), recipients who have left the client's business, and forms still sending to a developer's address from the original build. Fix those first. They are cheaper than any filter.

Standardise the cheap layers, move the judgement onto the message

Not every defence is wasted. The cheap, low-friction ones remove the crude end of the problem — scripts that post straight to the form endpoint, submissions with forty links — at almost no cost to real visitors.

Pick one baseline and apply it everywhere you can. A honeypot field or equivalent, sensible field validation, and one invisible or low-friction challenge if the client wants one. Choose the same components across every WordPress site so there is one set of settings to understand and one set of plugins to keep updated. Remove duplicates: a site running three overlapping anti-spam plugins is harder to debug than a site running one.

Stop trying to make the form decide everything. The part that is left after the cheap layers — polished, relevant-sounding messages that a real browser submitted — is hard to judge with rules at the form, because the only real evidence is what the message says. That judgement belongs after submission, where the message can be read, and where a decision can come with a reason someone can check. Our Contact Form 7 spam guide covers the plugin side of this in more detail.

Keep it outside the site where you can. Anything you can do without adding code to a client's theme is something that survives the client changing builders, redesigning or moving hosts. The recipient address in a form's notification settings is a setting almost every form builder has; the integrations list shows exactly where it lives in each.

Dry run first, then a threshold per client

Whatever filtering you introduce, do not switch it on for a client and hope. Run it for a week in a mode that delivers every message as normal and only records what it would have held.

At the end of the week, sit down with the client — fifteen minutes on a call is enough — and go through the report together. Two questions matter.

  1. Was anything that would have been held actually a real enquiry? If yes, the threshold is too strict for this client, or the message is a type they care about that you had not heard of. A clinic may discover that suppliers and referring practitioners use the same form.
  2. Is what got through acceptable? Some clients want to see every recruiter and every sales pitch. Others would rather never see them.

Agree the threshold in writing, and note the date. When the client later says "you blocked a customer", you have a record of what was agreed and why, and, if your filter records its reasons, you can look at the message and why it was held rather than guessing.

Recipients, the retainer and the monthly report

Recipients belong to the client. Do not keep an agency address on client form mail by default. Set recipients per client from the inventory, and have each person at the client confirm they want to receive enquiries before they do. It keeps personal data out of your mailboxes, and it means leavers at the client are the client's responsibility to report — which you should ask about at every review. The wider design questions — one owner per form, fallbacks, absences — are in our post on routing website enquiries.

Write it into the retainer. A line that says "spam protection" invites an argument. A line that says what you actually do does not: the forms covered, the threshold agreed, who receives mail, how held messages can be released, how quickly you respond to a report of a missed enquiry, and what the client must tell you (new forms, new staff, leavers).

Report monthly. One short paragraph per client: roughly how much was delivered and held, anything unusual such as a flood or a repeated campaign, anything released after review, and any changes made. Clients who can see the work stop asking whether it is being done.

Price it so volume is not your problem. The worst structure for an agency is a cost per message, because the client who is attacked hardest costs you the most in the month they are most annoyed. Look for flat pricing by client or by form. As one example, Humainbox's Agency plan is €299 a month for 25 client workspaces, priced by workspaces and inboxes rather than messages; the pricing page has the details. Whatever you use, you can then quote the client a fixed line in the retainer and keep the margin predictable.

Where it gets hard

Clients who insist on their own recipient lists. Some clients want everyone copied, including people who left last year. You can advise; you cannot decide. Put the recommendation in writing, and make sure new recipients have to confirm, so at least nobody receives enquiries without knowing.

Hosted builders you cannot log into. Some clients own their Wix or Squarespace account and will not share access. You cannot change the form yourself, so the change becomes a set of instructions for the client: which setting, which address, and a test submission afterwards to confirm it works. Budget time for chasing.

Handover when a client leaves. Plan the exit at the start. Know how the client's message history can be exported or deleted, and where the form's recipient needs pointing afterwards so enquiries do not stop on the day you hand over. If you act as a processor for the client under a contract, Article 28(3)(g) of the GDPR requires that contract to provide that the processor, "at the choice of the controller, deletes or returns all the personal data to the controller after the end of the provision of services". Whether that applies to your arrangement is a question for your own adviser, but the exit steps are worth agreeing before you need them.

Clients who want zero spam and zero risk. They cannot have both. Every threshold trades a little of one for the other, and the useful thing you can offer is not perfection but visibility: what was held, why, and a way to get it back.

Further reading

Stop contact form spam

Change one setting in your contact form. Spam stops arriving, and real enquiries go to whoever should answer them. Try it for a week with nothing switched on.

We would like to count visits with Google Analytics, which sets two cookies. Decline and nothing is loaded and nothing is sent. What these are.