Add Form Capture to Any Site Without a Backend
You don't need a server to collect form submissions. A plain HTML form and a submission endpoint is all it takes. Here's how.
The problem with contact forms
You have a static site. Astro, Next.js, Hugo, plain HTML, whatever. You need a contact form. But a form needs somewhere to send the data, and your static site doesn't have a server.
So you start looking at options. Formspree, Netlify Forms, Google Forms embedded in an iframe, a custom Lambda function, a Node.js server just for one form. Each one works. Each one adds a dependency, a separate dashboard, and another thing to maintain.
Here's the simpler version: point your HTML form at a submission endpoint. The endpoint stores the data, sends notifications, and fires webhooks. Your site stays static. No backend code.
The setup (5 minutes)
Step 1: Create a form in your dashboard. You get a unique endpoint URL.
Step 2: Point your HTML form's action at it:
<form action="https://form.attri.io/your-form-key" method="POST">
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message"></textarea>
<button type="submit">Send</button>
</form>
Step 3: There is no step 3. Submissions arrive in your dashboard.
No JavaScript required. No SDK. No build step. The form works with any site that can render HTML.
What you get back
Every submission includes the form fields plus context:
- UTM parameters from the visitor's URL (if they arrived via a tagged link)
- Referrer (where they came from)
- Country (from IP geolocation)
- Timestamp
- Session ID (if the tracking snippet is installed)
This is the part that generic form tools miss. Formspree tells you someone submitted a form. Attri tells you which campaign brought them there. That's the difference between "we got 30 leads" and "LinkedIn cpc drove 12 of those 30 leads."
Notifications
Set email notifications per form. Multiple recipients. When someone fills out your demo request at 2am, your sales team has it in their inbox before they wake up.
For real-time delivery to Slack, a CRM, or a spreadsheet, add a webhook URL. Every submission fires a POST request with the full data as JSON. Teams pipe this into Slack channels, HubSpot, Notion databases, and Zapier workflows without writing any code.
Bot protection
Public forms attract bots. Two layers handle this:
Turnstile CAPTCHA runs on every form. It's invisible to most real visitors. No "click every traffic light" puzzles.
Rate limiting at 10 submissions per minute per IP. A bot hammering your form hits the limit fast. A real person never will.
Both are on by default. No configuration needed.
When you'd want JavaScript
The plain HTML form works everywhere. But adding the JavaScript SDK gives you:
- AJAX submission — The page doesn't reload. Show a success message inline.
- Auto-injection of Turnstile — The CAPTCHA widget loads automatically.
- Field validation — Client-side checks before submission.
It's optional. Start with the HTML form. Add the SDK later if you need the UX polish.
Compared to other options
Google Forms. Free but the embed is an iframe that looks like Google Forms. You can't style it. No webhooks. No UTM attribution.
Formspree. Solid. Similar approach (endpoint URL). But no UTM attribution, no session tracking, and pricing starts at $8/mo for basic features.
Netlify Forms. Works great if you're on Netlify. Locked to the platform. No UTM context on submissions.
Custom backend. Maximum control but you're maintaining a server, a database, email delivery, and bot protection yourself. For a contact form.
Attri's form capture gives you the endpoint approach with attribution, webhooks, bot protection, and notifications built in. Free on paid plans, unlimited forms.