How to handle HTML form submissions without building a backend
Short answer: Change the form's action to a hosted endpoint and keep method="POST". The service accepts the browser's native form submission, validates it, stores it, and returns either a thank-you page or JSON if you submit with fetch().
You do not need a server to collect form data. You need an endpoint that already exists. This walkthrough starts from a form you have and ends with submissions you can read, without touching a framework.
Step 1: Create the form in the dashboard
Create a form, give it a name you will recognise in six months, and copy its endpoint. The URL contains a random id rather than a secret, so it is safe in public HTML.
Step 2: Point your form at it
<form action="https://formivo.faizyab.me/api/f/YOUR_FORM_ID" method="POST">
<label for="name">Name</label>
<input id="name" name="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
<button type="submit">Send</button>
</form>Field names become the JSON keys you see in the dashboard, so name them for the reader, not the database: `email`, not `field_2`.
Step 3: Decide what the visitor sees
| You want | Do this | The endpoint returns |
|---|---|---|
| A branded confirmation page | Nothing extra | HTML thank-you page, 200 |
| Your own thank-you page | Add `_redirect` with an https URL | 303 redirect |
| Stay on the page, show a message | Submit with fetch() and `Accept: application/json` | 201 with `{ success, leadId }` |
Step 4: Read the submissions
Submissions appear in the workspace immediately: filter by form, search across name, email, message, subject and phone, set a lead status, and export when the plan allows it. There is nothing to poll and no mailbox to keep clean.
Step 5: Add a little abuse control
- Add a hidden honeypot field (`_gotcha`). Submissions that fill it are answered with success and stored nowhere.
- Set an origin allow-list if the form should only accept posts from your domain.
- Keep rate limits on: per form, per IP and per form+IP are enforced in the database.
Common mistakes
- 1Leaving `method` off the form — the browser then sends GET and nothing is stored.
- 2Using `enctype="text/plain"`; only urlencoded and multipart are supported.
- 3Naming two inputs the same on purpose, then expecting one value.
- 4Blocking the submit button before the response returns, so a slow network looks broken.
That is the whole integration. One attribute, one form name, and a dashboard you can hand to a client without exposing your infrastructure.