Made in Calgary

Work with us
Web · Build Notes
September 16, 2026
10 min read

Your Contact Form Is Quietly Losing You Leads

The short answer. Two ways a contact form fails without telling you. A hosted form can stay open to direct posting long after you delete it from your site, which is how a scanner reached ours. And spam filtering judges whatever signals it receives, so a form that routes submissions through a server can end up looking like a bot to the filter. We hit both on our own site in September. The second one we caused ourselves while fixing the first.

The worst failure in lead generation is not the inquiry you lose to a competitor. It is the inquiry that arrived, got filed somewhere you never look, and left you believing the month was slow.

We rebuilt how forms work on this site over two days in mid-September, after two problems turned up a day apart. The first is a property of how our hosting platform handles forms rather than anything we had built wrong, and the second we introduced ourselves while fixing it.

Day one: the form nobody could close

On September 12, 2026, a scanner posted 100 submissions to our public contact form in 75 seconds, from 100 different IP addresses. Every field was empty apart from the payloads it was testing. Every one of them got past the honeypot and the spam filtering, and every one emailed both founders.

100 in 75s
Junk submissions through our public form on September 12, 2026, from 100 different addresses

Worth being precise about the honeypot, because it flatters the attacker to say the bots beat it. A honeypot is a hidden field that a real browser leaves empty and a naive bot fills in. A script posting straight at the endpoint never loads the page, never sees the field, and passes the check by not being there at all. It was not defeated. It was bypassed.

Nothing was breached, and the payloads were the automated sort sprayed at every site on the internet. That is rather the point. This was not a targeted attack; it was background noise finding an open door. The damage from that kind of event is not a hack. It is that your lead notifications become worthless for a day, so you start ignoring them, which is exactly when a real inquiry arrives.

Chasing it down turned up the more surprising problem. On our host, a form is not really part of your page. The page declares a form with a name, and the platform registers that name as a site-level object that accepts submissions. From that point the object exists independently of your website. Take the form out of your HTML, redesign the page, delete the page entirely, and the endpoint carries on accepting posts under that name.

We proved it twice, first on a preview build and then on production. An old contact form that no deployed page referenced anywhere was still accepting submissions. The only thing that closes one is deleting the form in the hosting dashboard. Other platforms may handle this differently, so the useful move is checking yours rather than assuming either way.

The practical consequence is that every form your site has ever had may still be open, and the names are often discoverable, because they sat in the page source while the form was live. Anyone who recorded one can post to it directly, skipping your page, your JavaScript and any validation you wrote.

Day two: the fix that started filtering our own test submissions

So we put a gate in front of everything. Forms now post to a server function that issues a short-lived token tied to the visitor, then checks that token on the way back in, along with the origin, the form name, the honeypot, the required fields, the shape of the email address, and whether the page value is actually a page. Only then does it forward the submission onward.

The token is the part that does the work. Rate limiting and origin checks are in there too, and both are worth having, but be honest about what they buy. The attack we had just seen used one submission per address across a hundred addresses, which is precisely the shape that walks through a per-IP rate limit, and origin headers are set by whoever sends the request. A control the attacker supplies is not a control. The token is the one a direct poster cannot mint.

That fixed the open door and created a quieter problem in its place. The forward carried the server's fingerprint rather than the visitor's: a data-centre IP address, a generic automated user agent, no referring page. To a spam service, that profile looks considerably more like a bot than a person on a laptop in Calgary. We had started submitting through a disguise that made ordinary submissions look suspicious.

We caught it the next day, testing through a real browser on a real connection and watching where each submission landed. Roughly one in seven was filed as spam, and none of those produced a notification. We did not record the exact denominator, so treat that as a small test run rather than a rate, and it is one site on one day rather than a general statistic. The mechanism is the part worth taking: the filter is judging signals you may be supplying on your customers' behalf, you are not seeing its decisions, and silence looks identical to no inquiries.

To be clear about the blast radius, every one of those was our own test submission. We caught it inside a day, so we have no evidence that a real inquiry was filtered. That is a short window and some luck, not a system working.

The forward now passes along the visitor's IP address, user agent, language and originating page, so the service is judging the person who actually filled out the form. Where it still files a genuine submission as spam, the function looks up its own record afterwards and marks the submission legitimate. That rescue is capped at twenty an hour per running instance, which is a soft ceiling rather than a hard one, since a busy site runs several instances at once.

One detail we had to run an experiment to settle: a row moved out of spam fires the notification like any other, so a rescued inquiry gets emailed rather than merely recovered in a dashboard. We would not have known that without testing it, and the rescue would have been close to worthless if the answer had gone the other way.

What to check on your own site

You do not need our setup to find most of this. Five checks. Four you can do yourself in an afternoon, and the fifth needs whoever holds the dashboard access.

The form audit

Submit your own form from your phone, on mobile datanot desk wifi
Open the spam folder in your form dashboardnot your email
Confirm where notifications goand who reads them
Check that submissions land somewhere besides emaildashboard or sheet
List every form the site has ever had, delete retired onesneeds dashboard access

The phone test is more important than it sounds. A form submitted from the same network and browser you built the site on is the least representative test available. Real customers arrive on mobile data, on a phone browser, sometimes with a VPN, often from a social app's in-app browser, which is the environment most likely to break a form and most likely to look unusual to a spam filter.

The spam folder check is the one that can find money, with a caveat. Most of the time you will open it and find several hundred pieces of genuine spam and nothing else, which is a useful result rather than a wasted trip. Some platforms also purge spam after thirty days, so there may be less history than you expect. Rather than reading every row, scan the sender names and domains for anything that looks like a person.

Getting submissions out of email alone is the durable fix. Email is a lossy destination: filters, a full mailbox, a departed staff member's address, a rule someone set up years ago. A copy of every submission in a dashboard or a sheet means a lost notification is an inconvenience rather than a lost customer. Treat that copy as what it is, a second store of other people's personal information, so keep access restricted and give it a retention period rather than leaving it in a link-shared spreadsheet forever.

One warning from our own week: test submissions are real submissions. Ours emailed both founders roughly thirty times in a day. If you are going to test properly, turn the notifications off for the duration and back on afterwards, and never run a test against someone else's live site without asking the owner first.

The honest caveat

Everything above is one agency's experience on one site over a few days in September, on one platform. Other platforms handle spam and form lifecycle differently, and some of them handle it better. We are not claiming a general law about contact forms, and the ratio we measured is not a benchmark.

What does generalize is the shape of the problem. Any system that filters on your behalf, notifies you selectively, and keeps accepting input after you think you have removed it will fail quietly rather than loudly. Quiet failures are the ones that go uncorrected for a year, because nothing ever tells you to look.

Frequently asked questions

How do I know if my contact form is actually working?

Submit the form yourself from a phone on mobile data rather than office wifi, and then confirm the submission arrives in both the notification email and the form dashboard, including the dashboard's spam folder. A form that appears to submit successfully in the browser can still be filtered before any notification is sent, so a front-end test on your own office network proves very little.

Why would a real inquiry end up in spam?

Hosted form products commonly run submissions through an automated spam service, and on some platforms that check cannot be disabled. The service scores signals such as the sending IP address, the browser's user agent and the referring page. A site that forwards submissions through its own server can end up supplying the server's signals instead of the customer's, which makes ordinary inquiries look automated. That is a mistake we made on this site and had to correct.

Does deleting a form from my website stop it receiving submissions?

Not necessarily. On our host, a form is a site-level object identified by name, and ours kept accepting direct submissions after the form was removed from every deployed page. Closing it required deleting the form in the hosting dashboard, after exporting anything worth keeping. Other platforms may behave differently, so a retired form is worth verifying rather than assuming closed.

Is a honeypot field enough to stop form spam?

A honeypot field is not enough on its own, because it only filters bots that load your page. A script posting directly at the form endpoint never renders the hidden field and passes the check by omission, which is how 100 junk submissions reached us in 75 seconds from 100 addresses. A honeypot is still worth keeping for naive bots, but the control that actually closes direct posting is a server-issued token the sender cannot mint.

Where should form submissions be stored?

Form submissions should be stored somewhere besides email alone. Email is a lossy destination: notifications get filtered, mailboxes fill up, and addresses belong to people who leave. Keeping a copy in a dashboard, sheet or CRM means a missed email costs a delay rather than a customer. That copy holds personal information, so restrict who can open it and give it a retention period.

Related reading

Build notes

We will help you check your own form.

Send us your site and we will list every form name still findable in your published source, then walk your own test submission through with you at a time you pick, so you can watch your dashboard, inbox and spam folder for where it lands. No charge, and no pitch attached if everything is fine.

Talk to us