How to Collect Form Submissions Without a Backend
You don't need a server to collect form data. Point your HTML form at a Postbox endpoint and get validation, spam filtering, and notifications out of the box.
You built a landing page. Maybe you prompted it into existence with an AI tool. Maybe you hand-wrote every line. Either way, you have an HTML form and nowhere to send the data. The form has an action attribute pointing at nothing.
The traditional answer is: build a backend. Spin up a server, write a POST handler, validate the input, store it in a database, send yourself an email. For a contact form. That collects a name, an email, and a message.
There’s a better answer. Point your form at an endpoint that already handles all of that.
The problem with rolling your own
Building a submission handler sounds simple until you list everything it needs to do.
Validation. You need to check that required fields are present, that emails look like emails, that types match expectations. Client-side validation helps, but it’s trivially bypassed. Server-side validation is mandatory.
Storage. The data needs to go somewhere persistent. A database, at minimum. With a schema, migrations, and a way to query it later.
Spam filtering. The moment your form goes live, bots find it. You need reCAPTCHA, honeypot fields, or some kind of content analysis. Otherwise your inbox fills with garbage within days.
Email notifications. You want to know when someone submits. That means an email service, templates, delivery monitoring.
CORS. If your frontend is on a different domain than your backend (and with static sites, it always is), you need to handle cross-origin resource sharing headers correctly.
That’s five separate concerns for a contact form. Each one is a dependency, a potential failure point, and a maintenance burden. And you haven’t even started building whatever your actual product is.
The endpoint approach
Postbox gives you an HTTP endpoint that handles all five. You create a form in your Postbox dashboard, define what fields it accepts, and get a URL. Point your HTML form at that URL. Done.
Here’s the complete flow.
1. Create a Postbox form
Sign up at usepostbox.com and create a new form from the dashboard. Define a schema with the fields you want to collect:
{
"fields": [
{ "name": "name", "type": "string", "required": true },
{ "name": "email", "type": "email", "required": true },
{ "name": "message", "type": "string", "required": false }
]
}Every submission is validated against this schema. If someone (or something) sends data that doesn’t match, it gets rejected with a clear error. No junk data in your inbox. Read why structured schemas matter for the full rationale.
2. Get your endpoint URL
Go to the Integration tab on your form. You’ll see an endpoint URL and auto-generated code snippets. The URL looks like:
https://usepostbox.com/api/{opaque_segment}/f/{slug}
When you update your schema, you get a new URL. Old URLs keep working with the schema version they were created for. Nothing breaks.
3. Connect your HTML form
Here’s a complete, working example. No build tools, no framework, no dependencies:
<form id="contact-form">
<label for="name">Name</label>
<input type="text" id="name" name="name" required />
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="message">Message</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Send</button>
<p id="status"></p>
</form>
<script>
const POSTBOX_URL = "YOUR_ENDPOINT_URL";
document
.getElementById("contact-form")
.addEventListener("submit", async (e) => {
e.preventDefault();
const form = e.target;
const status = document.getElementById("status");
const res = await fetch(POSTBOX_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: form.name.value,
email: form.email.value,
message: form.message.value,
}),
});
if (res.ok) {
form.reset();
status.textContent = "Thank you! Message sent.";
} else {
const errors = await res.json();
status.textContent = Object.values(errors).join(", ");
}
});
</script>
Replace YOUR_ENDPOINT_URL with the URL from your Integration tab. Deploy this anywhere: a static site on Netlify, a GitHub Pages repo, an S3 bucket, your own server. It doesn’t matter. The form submits to Postbox over HTTPS, and Postbox handles everything after the POST.
CORS is enabled by default on all Postbox endpoints. Your frontend can submit from any origin without configuration.
What happens after submit
When a submission hits your Postbox endpoint, here’s the sequence:
-
Schema validation. Fields are checked against your schema definition. Missing required fields or type mismatches return a
422response with field-level errors. -
Storage. Valid submissions are persisted immediately. You get a
201response with the submission ID. -
Processing pipeline. In the background, Postbox runs whatever you’ve configured: spam filtering catches bot submissions and junk content, auto-translation converts submissions into your preferred language, and smart replies can auto-respond to common questions using a knowledge base you define.
-
Notifications. You get an email with the submission data. View it in your dashboard in real time.
The submitter gets an instant response. Processing happens asynchronously. No waiting.
This works for more than contact forms
The same endpoint that your HTML form submits to also accepts data from cURL commands, Python scripts, Node.js services, and AI agents. The schema validation is identical regardless of the source.
Common use cases beyond contact forms:
- Waitlist signups. One field: email. Enable spam filtering. Done.
- Feedback forms. Collect ratings, feature requests, and bug reports with typed fields.
- Event RSVPs. Name, email, plus-one count, dietary restrictions. All validated.
- Survey responses. Multiple fields with required/optional flags enforced server-side.
- Lead capture. Company name, role, use case. Pipe into your CRM via webhooks.
Every one of these would traditionally require a backend. With Postbox, each is a form with a schema and an endpoint URL.
Compared to building it yourself
Here’s what you skip by using an endpoint instead of building a backend:
- No server to provision, deploy, or keep running
- No database to manage, back up, or migrate
- No email service to integrate
- No spam filtering to implement and tune
- No CORS headers to debug
- No validation logic to write and maintain
You write HTML and a fetch call. Postbox handles the rest. If your needs change, update the schema and get a new endpoint. Old endpoints keep working. Your deployed frontend doesn’t break.
Getting started
The free plan includes one form with 5,000 lifetime submissions and 50 AI credits for spam filtering, translation, and smart replies. Enough to run a contact form on a personal site indefinitely, or to test the platform before committing.
Sign up at usepostbox.com, create a form, copy your endpoint URL, and paste it into your HTML. The entire process takes about two minutes. Read the complete HTML form guide for a deeper walkthrough including framework-specific examples and error handling patterns.