When building websites for clients, I kept running into the same problem in two different flavours. The first was spam. Contact forms, newsletter signups, job applications: all of them attracted bots the moment they went live. Clients would call saying they were getting tens of submissions a day, almost none of them real. The second problem was subtler: forms that appeared to be working but weren’t. Email delivery would silently fail. A webhook would time out. Nobody noticed until a client mentioned they hadn’t heard from customers in weeks.
Lots of projects needed a form backend, and each one needed spam protection, reliable delivery, and a way to know when something broke. I rebuilt the same solution from scratch more times than I can count. That’s why I built StaticForm.
Two Problems That Look Simple Until They Aren’t
Most websites need forms. Building an HTML form takes minutes. Making it reliable is where the work actually starts.
The spam problem was the visible one. Within days of a form going live, the inbox would start filling with junk. Bots hit public endpoints constantly, and their submissions look identical to real messages. Around 95% of form traffic across the web is spam, and you only find out which messages are real by opening each one and reading it, so that’s mostly what clients were doing. It made the form feel useless even when it was technically fine.
The second problem was quieter, which made it worse. A form could be completely broken and nobody would know. Email delivery would fail without any error message. A webhook would hit a timeout. An SMTP quota would be reached. The form would still say “thank you” to whoever submitted it, and the submission would just go nowhere. I had clients who’d gone weeks without realising they weren’t getting any enquiries, not because nobody was contacting them, but because nothing was getting through.
Often when I solved these for a client, I was also managing platform fragmentation on top of it. Static site generators, WordPress, GitHub Pages, Netlify, and Vercel all need the same backend solution but reached through completely different paths. And each project’s solution was isolated, with no shared dashboard or centralized view.
The Solution: StaticForm
I built StaticForm to handle all of this in one place. The core idea was simple: configure a form in a dashboard, get an endpoint URL, put that URL in the form’s action attribute, and you’re done. You pick where submissions should go (email, Slack, Discord, a webhook) and StaticForm handles everything that happens after someone hits submit, including storing the submission in Europe regardless of whether the notification gets through. The whole thing takes about five minutes to set up.

What I Built
Building StaticForm meant solving one core challenge: handling all the failure modes that were causing problems in practice, while keeping the setup simple enough that you don’t have to think about any of it.
Spam Filtering
Spam protection became the thing I spent the most time on, because it’s the hardest part to get right at scale. There are now more than ten checks running on every submission: honeypot traps that catch basic bots, IP reputation blocking against known spam sources, datacenter IP detection (most bots run from cloud providers, not home connections), disposable email address filtering, domain age checks, email domain validation, content analysis for suspicious patterns, and detection for cold pitch emails: the kind of “I noticed your website could benefit from better SEO” messages that are mostly auto-generated templates.
One thing I find particularly interesting is the deception layer. StaticForm returns a 200 OK to spam submissions rather than an error. Bots that get errors adapt; they retry different payloads, rotate IPs, change tactics. Bots that get a 200 OK think they succeeded and move on. The effect compounds over time: spam sources stop targeting your endpoint without knowing they’ve been filtered. Caught submissions disappear before they reach any notification channel.

Observability
The problem I kept running into with existing form tools wasn’t just spam; it was having no idea when something broke. Email delivery fails silently. Webhooks time out without alerting anyone. A submission goes nowhere and nobody finds out until a client mentions they haven’t heard from customers in two weeks.
StaticForm logs every action against every submission, with the result and any error detail. If email delivery fails, you can see exactly why (SMTP error, mailbox full, rejected by recipient server) and when it happened. If a webhook times out, that’s logged too. When something breaks, you get alerted immediately rather than finding out when the client does.
Every submission is stored first, before any notification goes out. This means you can retry a failed notification from the dashboard with a single click, against a submission that was safely written to storage the moment it came in. Nothing is lost because a downstream service had a bad day.

Notifications and Delivery
Email fails more often than people realise. SMTP servers go down, inboxes hit quotas, messages land in spam folders. That’s why StaticForm supports multiple notification channels running simultaneously. You can send to email and Slack and Discord and a custom webhook all at once, whichever combination makes sense for the project.
File uploads work alongside form data as well. Job applications with resumes, contact forms with attachments, anything involving document submissions. Files are stored securely and downloadable from the dashboard.

Easy Integration
From a developer’s perspective, the integration is just an HTML form pointing at an endpoint URL. You write the form the same way you always would, and StaticForm takes it from there. The dashboard generates ready-to-paste code snippets for plain HTML, and a version using the staticform.js helper script that handles validation, loading states, and error feedback out of the box. For framework-specific code, there’s also a generated AI prompt you can hand to Claude, Codex, or any AI agent of choice. It works on Jekyll, Hugo, Gatsby, Next.js, Astro, GitHub Pages, Netlify, Vercel, Cloudflare Pages, WordPress, or any platform that can POST to an endpoint.

The Technical Foundation
Behind that simple setup is infrastructure built for reliability. The API gateway handles every submission with rate limiting, validation, and queue processing. If traffic spikes, nothing gets dropped. If a downstream service is slow, submissions wait in the queue until they’re processed.
The one rule the architecture is built around: data persistence comes first. Before a single notification goes out, every submission gets written to storage. This ordering means that even if the entire notification system fails, you never lose a submission.
Everything runs in containers deployed via CI/CD pipelines. Infrastructure as Code means the entire platform can be recreated from configuration files. Monitoring and alerting run 24/7. The platform maintains 99.9% uptime because it’s built to handle failures gracefully: services restart automatically, queues buffer traffic spikes, database connections are pooled, rate limiting prevents abuse.
Built for Managing Multiple Sites
The dashboard is also built for managing many forms and many clients from a single place. Every form can be tagged by client or site, giving you one view across all your client forms (submissions, statuses, recent failures) without switching accounts. You can invite clients so they have their own access, or route notifications directly to them so they stay in the loop without logging in, or both.
The observability matters most in this context. If a client’s form is silently failing, the execution log shows it. You can spot and fix the issue before the client notices. And since pricing is a flat monthly fee regardless of how many forms or clients you add, the per-project overhead for form handling effectively goes to zero.

What I Learned
Building StaticForm taught me that product work is fundamentally different from client work:
Product decisions are harder than technical decisions. The technology choices were straightforward. The hard part was figuring out pricing, which features matter most, and what problems to prioritize. There’s no client to tell you what they need, at least not when you’re starting out.
Marketing is harder than building. I can build a form backend in a few weeks. Getting people to trust it enough to use it? That’s the real challenge. I’m learning to provide value on platforms like Reddit, reach out to agencies, developers, and communities, and let real conversations do the work.
Support never ends. Client projects often have a clear end point. A SaaS product runs forever. Every user expects 99.9% uptime. That responsibility shapes everything.
Simplicity wins over features. My first instinct was adding every feature possible. But what makes StaticForm useful is that it does a few things extremely well. Less complexity means more reliability.
Pricing structure matters. I started with a credit-based model where spam didn’t count against the customer’s balance. It was a reasonable alignment of incentives, but it introduced friction; potential users had to estimate how many credits they’d need. The current model is built around the idea of paying for features, not submissions. Both plans include unlimited submissions and unlimited forms. What’s capped instead are things with real per-unit costs: email actions (25,000/month on Starter, unlimited on Pro) and file storage. Spam never counts against any of those limits. The incentive alignment is cleaner: I have every reason to filter aggressively, because spam that slips through costs me resources, not the customer.
Current Status
StaticForm is live and processing submissions for paying customers across multiple countries. The platform maintains 99.9% uptime and handles everything from simple contact forms to complex job applications with file uploads.
Pricing is a flat monthly fee with unlimited submissions. You can try it without a credit card. A WordPress plugin is in development for sites that want native CMS integration.
The goal remains the same: spam blocked before it reaches anyone, full visibility into every submission, fair pricing with no surprises, and an integration that takes minutes to set up. If you want to take a look, it’s at staticform.app.
I’m always open to feedback, feature requests, and hearing about how you’re using the platform. Feel free to reach out if you have ideas or run into any issues.