Quickstart
FormWire is a form backend for static sites: point any HTML form at one endpoint and every POST becomes an email in your inbox and a stored record you can query. No server, no SDK, no build step.
-
Get your access key. Sign up and copy your access key from the dashboard. It’s public by design: it can only ever deliver mail to recipient addresses you’ve verified, so it’s safe to ship in your HTML.
-
Point your form at the endpoint. Set your form’s
actiontohttps://api.formwire.io/submitand add the key in a hiddenaccess_keyfield. Every named input becomes a line in the email. -
Submit and check your inbox. Send a test submission. It appears in your dashboard immediately and typically lands in your inbox within seconds.
Pick your stack
Section titled “Pick your stack”Replace YOUR-ACCESS-KEY with the key from your dashboard.
<form action="https://api.formwire.io/submit" method="POST"> <!-- Your access key (safe to expose: delivery is locked to your email) --> <input type="hidden" name="access_key" value="YOUR-ACCESS-KEY">
<!-- Any named inputs become the email body --> <input type="text" name="name" required> <input type="email" name="email" required> <textarea name="message" required></textarea>
<!-- Honeypot: hidden from humans, catches bots (default field name: fax_number) --> <input type="text" name="fax_number" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-9999px" value="">
<button type="submit">Send</button></form>const form = document.querySelector("#contact-form");
form.addEventListener("submit", async (e) => { e.preventDefault(); const data = Object.fromEntries(new FormData(form));
const res = await fetch("https://api.formwire.io/submit", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ access_key: "YOUR-ACCESS-KEY", ...data }), });
if (res.ok) { form.replaceWith("Thanks, we'll be in touch."); } else { const { message } = await res.json(); alert(message || "Something went wrong. Please try again."); }});import { useState } from "react";
export function ContactForm() { const [sent, setSent] = useState(false);
async function onSubmit(e) { e.preventDefault(); const data = Object.fromEntries(new FormData(e.currentTarget)); const res = await fetch("https://api.formwire.io/submit", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ access_key: "YOUR-ACCESS-KEY", ...data }), }); if (res.ok) setSent(true); }
if (sent) return <p>Thanks, we'll be in touch.</p>; return ( <form onSubmit={onSubmit}> <input name="name" required /> <input name="email" type="email" required /> <textarea name="message" required /> <button>Send</button> </form> );}<!-- Add enctype and a file input. Attachments arrive with the email. (File uploads are a Pro-plan feature.) --><form action="https://api.formwire.io/submit" method="POST" enctype="multipart/form-data"> <input type="hidden" name="access_key" value="YOUR-ACCESS-KEY">
<input type="email" name="email" required> <input type="file" name="attachment">
<button type="submit">Send</button></form>Where to next
Section titled “Where to next”- Submit API reference — request formats, responses, error codes, and updating a submission
- Special fields —
_redirect,_ccand friends - File uploads — attach files with
multipart/form-data - Auto-reply — confirm receipt to the submitter
- Webhooks — receive submissions at your own endpoint, with signatures
- Read API — pull submissions as JSON
- Spam protection — honeypot, hCaptcha, reCAPTCHA, Turnstile
Troubleshooting
Section titled “Troubleshooting”No email arrived. Check three things in order: (1) your dashboard — if the submission is there, delivery is the issue, so check your spam folder and confirm your address is verified; (2) your access_key value matches the dashboard exactly; (3) the browser’s network tab — the API returns a JSON error message explaining what was rejected. See error codes.
Testing without polluting real data. Forms are unlimited on every plan. Create a second form just for testing, each with its own key.