HTML contact forms
without a backend.
Connect a plain HTML form to Form Plume and collect messages, get email notifications, filter spam, accept files, and trigger integrations without managing PHP, databases, or email providers.
<form action="https://api.formplume.com/f/8kq2zr" method="POST">
<label for="name">Name</label>
<input id="name" name="name" required />
<label for="email">Email</label>
<input id="email" type="email" name="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<button>Send message</button>
</form>The full guide
A complete backend for your HTML form.
Follow the guide below to connect a plain HTML form to Form Plume. Your first 500 submissions are free, so you can test the full flow before committing.
- 1Create your Form Plume accountStart free and give your HTML form a hosted endpoint.Start free
- 2Create your first form and copy the endpoint URLAfter you log in, create a form and copy its endpoint. It looks like
https://api.formplume.com/f/your-slug - 3Paste the endpoint into your form actionUse the HTML example below, then add optional redirects, uploads, integrations, and spam controls as needed.
You can use this AI prompt to speed up your integration.
Build the form with real HTML
Start with the browser's native form behavior. A plain <form> can send the submission directly to Form Plume, redirect after success, and keep working even when JavaScript fails to load.
Replace PASTE_YOUR_FORM_PLUME_ENDPOINT_HERE with the endpoint you copied from Form Plume.
<form action="PASTE_YOUR_FORM_PLUME_ENDPOINT_HERE" method="POST">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required>
<label for="email">Email</label>
<input id="email" type="email" name="email" autocomplete="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<button type="submit">Send message</button>
</form>That is the whole backend integration. The browser posts the fields to Form Plume, and Form Plume stores the submission, sends email notifications, runs spam protection, and can trigger integrations.
Name the fields clearly
Use field names that describe the data you want to read later. Form Plume accepts custom fields, but predictable names make email notifications, exports, integrations, and team handoff easier.
Use name for the sender's name, email for the reply address, and message for the main message.
Add fields like company, phone, subject, budget, or source only when they make the form more useful.
Every field that should arrive in Form Plume needs a name attribute. Fields without name are visible to the visitor, but the browser does not include them in the submission.
Add a custom thank-you page
By default, Form Plume can show a hosted success page after a valid submission. If you want visitors to land on your own page instead, add a hidden _redirect field.
<input type="hidden" name="_redirect" value="/thanks">Use a root-relative path for the same site or an absolute URL when you want to send visitors somewhere else.
Keep the redirect page useful. Confirm that the message was received, tell the visitor what happens next, and include a way back to the rest of your site.
Add error messaging without JavaScript
Browsers already know how to validate required fields and email inputs. With required and type="email", visitors get baseline validation before the form submits.
If you add helper text, connect it to the field with aria-describedby so assistive technology reads the hint with the input.
<label for="email">Email</label>
<input
id="email"
type="email"
name="email"
autocomplete="email"
aria-describedby="email-hint"
required
>
<p id="email-hint">We'll only use this to reply to your message.</p>Server-side validation still matters. Anyone can remove HTML attributes before sending a request, so Form Plume validates accepted submissions after they reach the endpoint.
Enhance it with JavaScript, if you want it
JavaScript is optional. Use it when you want the visitor to stay on the same page and see an inline success or error message.
Add Accept: application/json to the request and Form Plume returns JSON instead of redirecting.
const form = document.querySelector("form");
const status = document.getElementById("status");
form.addEventListener("submit", async (event) => {
event.preventDefault();
status.textContent = "Sending...";
const response = await fetch(form.action, {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
status.textContent = response.ok
? "Thanks, we got your message."
: "Something went wrong. Try again.";
});Add a status element near the submit button.
<p id="status" role="status"></p>This is progressive enhancement. If the script fails, the original <form action method="POST"> still works.
Best practices
Keep the endpoint in one place in your template so it is easy to replace when you move from a test form to a production form.
Use visible labels instead of placeholder-only fields. Placeholders disappear while typing and are harder to scan.
Ask for the fewest fields you need. Short forms usually convert better, and clean submissions are easier to route into email, integrations, and CRM workflows.
Use autocomplete for common fields like name, email, tel, organization, and address-level2.
Add hidden fields for context only when they help. Good examples are source, campaign, page, or plan.
File uploads
Use multipart/form-data when the form includes files.
<form
action="PASTE_YOUR_FORM_PLUME_ENDPOINT_HERE"
method="POST"
enctype="multipart/form-data"
>
<label for="attachment">Attachment</label>
<input id="attachment" type="file" name="attachment" accept=".pdf,.png,.jpg">
<button type="submit">Send message</button>
</form>Form Plume stores attachments separately from email delivery, so a large file does not break the notification path.
See File Uploads for limits and stored-file behavior.
Integrations and webhooks
An HTML contact form can trigger more than an email.
Form Plume can store the submission, notify your team, and send accepted submissions into the tools where work happens next.
Use integrations for common tools like Slack, Discord, Google Sheets, Mailchimp, and ActiveCampaign.
Use webhooks when you want to send submissions to your own API, automation platform, CRM, or internal workflow.
That keeps your static site simple. The form submits once, and Form Plume handles the fan-out.
Spam protection
Contact forms attract spam as soon as they are public.
Form Plume layers a honeypot field, a submission time trap, rate limiting, and content checks before the submission reaches your inbox or integrations.
Start with the defaults, then add stronger checks when a form starts getting targeted abuse.
See Spam Protection for honeypots, rate limits, submission timing, and how suspicious messages are handled.
Accessibility
Every field needs a visible label connected with for and id.
Use required, type="email", and helpful hints to reduce preventable errors.
Use role="status" for inline success messages and role="alert" for inline errors when you add JavaScript enhancement.
Keep focus behavior predictable. After a failed validation, the browser should move the visitor to the field that needs attention.
Where this runs
Because this is a plain <form> with an action, it works on static HTML, Jekyll, Hugo, Eleventy, Astro, WordPress, Webflow, Framer, Carrd, and any static-site generator output.
There is no build step, server function, API route, database, or email provider for you to maintain.
Primary sources
FAQ
HTML form questions
before you ship.
One line. Zero backend.
