There is a version of contact form spam that costs money rather than time, and it is worth separating from the rest.
If your contact form fires a conversion event, every submission teaches the campaign something. Smart Bidding does not know which of them were real. It knows that a particular audience, placement or search term produced conversions, so it buys more of that traffic. Junk submissions do not merely waste your morning. They become the training data, and the campaign optimises toward the source that produced them.
The people this happens to describe it consistently. Submissions arriving as spam within hours of a campaign going live. Names and phone numbers that look real until somebody dials them and the person has never heard of you. Budget spent, faithfully, on getting more of it.
We do not solve this, and this post is not a sales pitch. Humainbox sits between the form and the mailbox, which is downstream of the problem described here: by the time we see a submission, your conversion tag has already fired and the bidding has already learned from it. What follows is what actually works, none of which is us.
Why the usual defences do not help here
reCAPTCHA and Turnstile answer the question "is this a human?" That question has become answerable — an agentic browser drives a real browser, with a real fingerprint, from a residential address, and behaves like a person because in the ways being measured it is indistinguishable from one. We wrote about why that shift broke CAPTCHA separately.
A honeypot still catches the crude end of this, and it is free, so keep it. It will not catch a browser that fills the form the way a person would.
And a mailbox-side filter — ours or anyone's — is by definition too late. The tag fires when the form submits, not when the mail arrives.
What actually works
Gate the conversion event, not the form. The most effective change is to stop treating "form submitted" as a conversion. Fire the tag on a condition you control: a honeypot field that must be empty, a minimum time-on-form, a server-side validation that has to pass first. In Google Tag Manager this is a trigger condition rather than a new tool. Submissions still arrive; they just stop teaching the campaign.
Move the conversion further down. If a lead only counts once somebody has qualified it, import that instead. Offline conversion import takes the GCLID captured at submission and sends back the outcome — qualified, not qualified — days later. The bidding then learns from outcomes rather than from form fills. This is more work to set up than anything else here, and it is the only approach that survives a spammer who learns your gating rules.
Exclude what you can see. Placement exclusions on Display and PMax, and the content-suitability settings, remove a measurable share of automated traffic. It is a blunt instrument and it is not nothing.
Check what you are counting before you change anything else. A campaign with two conversion actions, one of which is "form submitted" and one of which is "qualified lead", will tell you within a week which of your sources produces which. That is usually cheaper than any tooling decision.
Where a mailbox filter does start to matter
Once the campaign has stopped learning from junk, the junk still arrives — it just no longer costs you ad spend. It costs whoever reads it. Roughly ten seconds per message, several dozen times a day, taken from the person whose actual job is answering the real ones.
That is the part we work on, and it is a different problem with a different cost. If you got here because your conversion data is polluted, fix the tag first. We will still be here afterwards, and we would rather you arrived knowing which of the two problems you were solving.