Form Backend lets a static website receive form submissions without a server. This page documents exactly what the endpoint does today, nothing more, nothing less.
Sign up with your email address and sign in. No credit card is needed for the Free plan.
In the dashboard, create a form and set the notification email, the address that receives each submission.
The form's detail page shows its endpoint URL and a ready-made HTML snippet. Every form has its own key, so you can use different forms for different pages or sites.
Paste the snippet into your page (see the example below), or point an existing form's action attribute at the endpoint.
Send a test submission from your live page. It appears under Submissions in the dashboard and arrives in your notification inbox.
Each form accepts submissions at one URL:
https://form-backend-tool.vercel.app/api/forms/YOUR_FORM_KEYReplace YOUR_FORM_KEY with your form's public key from the dashboard. Three content types are accepted:
application/x-www-form-urlencoded, what a normal HTML form sendsmultipart/form-data, also what a normal HTML form sends (file parts are ignored, see below)application/json, for JavaScript fetch callsThe endpoint sends CORS headers (Access-Control-Allow-Origin: *), so forms on any domain can post to it.
A complete, working contact form. Replace YOUR_FORM_KEY with your own key and drop it into any HTML page:
<form action="https://form-backend-tool.vercel.app/api/forms/YOUR_FORM_KEY" method="POST">
<label>Your name <input type="text" name="name" required></label>
<label>Your email <input type="email" name="email" required></label>
<label>Message <textarea name="message" required></textarea></label>
<!-- Optional: after a successful submit, send the visitor to your own page.
Must be an absolute http:// or https:// URL. -->
<input type="hidden" name="_redirect" value="https://your-site.example/thanks">
<!-- Honeypot: leave this empty and hidden. People never see it;
bots fill it in, and those submissions are flagged as spam. -->
<input type="text" name="_honey" style="display:none" tabindex="-1" autocomplete="off">
<button type="submit">Send</button>
</form>HTML is the simplest route, not the only one. The endpoint accepts standard form posts and JSON from any technology that can send an HTTP POST request, React, Next.js, Vue, PHP, Python, WordPress, Laravel, Django, Flask, Node.js, and others. There is no SDK to install and nothing stack-specific to configure: every stack posts the same fields to the same endpoint.
From JavaScript (React, Next.js, Vue, or a plain page):
await fetch("https://form-backend-tool.vercel.app/api/forms/YOUR_FORM_KEY", {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
name: "Ada",
email: "ada@example.com",
message: "Hello from my app",
}),
});From a server or a CMS (PHP, Python, Laravel, Django, Flask, WordPress): send the same fields as a form post (application/x-www-form-urlencoded) or JSON, from your form handler, a webhook setting, or your form tool's POST action, using whatever your stack already uses to make an HTTP request.
name, email, phone, company, …) is stored exactly as named and shown in the dashboard and the notification email. There is no required schema, a form with only a message field is fine._honey (honeypot) and _redirect (success redirect).Include the _honey input from the example, hidden with display:none. Real visitors never see or fill it; automated bots typically fill every field. When _honey arrives filled in:
On top of the honeypot, each form is rate-limited per visitor, which slows down submission floods (see Limits).
_redirect field with an absolute http:// or https:// URL, and a successful submit answers with a 303 redirect to that page, ideal for your own thank-you page. Invalid or relative values are ignored._redirect: if the request accepts JSON (e.g. a fetch call with Accept: application/json), the response is { "ok": true, "message": "Submission received." }. A plain browser form post gets a simple built-in thank-you page with status 200.{ "ok": false, "error": "…" } for JSON callers, a small HTML error page for browser posts. Status codes are listed in the error reference.Every stored submission is listed in the dashboard, grouped by form, with All / Unread / Spam filters. You can open a submission to see every field, mark it read or unread, and delete it. Each form's submissions can be downloaded as a CSV (from the form's page) for use in a spreadsheet. The overview shows this month's usage against your plan limit.
Invalid submission data. / Submission is empty.The body could not be parsed, or every field was empty after cleaning.
This form is not accepting submissions.The form exists but is paused/disabled in the dashboard.
Form not found.The key in the URL is invalid or no form has that key. Check for typos.
Method not allowed. Use POST.The endpoint was called with GET or another method instead of POST.
Submission is too large.The submission exceeded the payload limit (25 KB by default).
Unsupported content type.Use application/x-www-form-urlencoded, multipart/form-data or application/json.
Too many submissions. Please try again later.Rate limit hit: too many submissions from one visitor in a short window (10 per 60 seconds by default).
This form has reached its monthly submission limit.The form's monthly quota (250 on the Free plan) is used up. It resets on the 1st of the next month.
Could not process submission. / Could not store submission.A server-side problem on our side. The submission was not stored; ask the visitor to retry.
Form service is not configured yet.This deployment's backend is not fully configured. (You should not see this on the hosted service.)
If this page does not answer your question, visit the support page for the contact channels. The founder answers support himself.