HTML & JavaScript
Submit FormsFort forms from plain HTML or JavaScript with JSON, FormData, client-side validation, and inline result rendering.
HTML & JavaScript
Keep visitors on the page with browser-side submissions. Use plain HTML for the simplest path, or add JavaScript when you want inline status, custom validation, or a framework-free AJAX flow.
Patterns
Plain HTML
Use the form action directly when a full-page success or redirect flow is acceptable.
Fetch JSON
Prevent default submission, send JSON to the public endpoint, and render success or error state in place.
FormData
Send multipart FormData when the form includes file inputs.
Validation
Run client-side validation for user experience, then rely on server validation for enforcement.
Plain HTML
<form id="contact-form">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<input type="hidden" name="subject" value="New website lead" />
<input type="checkbox" name="botcheck" style="display:none" />
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
<p id="form-result" role="status"></p>
</form>JavaScript JSON submit
const form = document.querySelector("#contact-form");
const result = document.querySelector("#form-result");
function formDataToJson(formData) {
const payload = {};
for (const [key, value] of formData.entries()) {
if (payload[key] === undefined) {
payload[key] = value;
continue;
}
payload[key] = Array.isArray(payload[key]) ? [...payload[key], value] : [payload[key], value];
}
return payload;
}
form.addEventListener("submit", async (event) => {
event.preventDefault();
result.textContent = "Sending...";
const response = await fetch("https://api.formsfort.dev/submit", {
method: "POST",
headers: {
accept: "application/json",
"content-type": "application/json",
},
body: JSON.stringify(formDataToJson(new FormData(form))),
});
const body = await response.json();
result.textContent = body.message || (response.ok ? "Submitted." : "Submission failed.");
if (response.ok) {
form.reset();
}
});Multipart FormData submit
Use FormData directly when uploads are enabled. Do not set the content-type header; the browser adds the multipart boundary.
const response = await fetch("https://api.formsfort.dev/submit", {
method: "POST",
headers: { accept: "application/json" },
body: new FormData(form),
});Response contract
{
"success": true,
"message": "Email sent successfully!",
"requestId": "req-id",
"deliveryId": "delivery-id"
}{
"success": false,
"message": "Missing access_key.",
"requestId": "req-id"
}Validation notes
Browser validation improves feedback but does not replace API checks. FormsFort still validates the access key, entitlement gates, domain restrictions, captcha tokens, uploads, rate limits, abuse rules, and destination addresses server-side.