Examples
Drop-in HTML page with a working form
A complete HTML page with a waitlist form that posts to form-relay. Swap in your endpoint slug and API key.
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Join the waitlist</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 480px; margin: 4rem auto; padding: 0 1rem; }
label { display: block; margin-bottom: 0.25rem; font-size: 0.875rem; }
input { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #ccc; border-radius: 6px; margin-bottom: 1rem; font-size: 1rem; box-sizing: border-box; }
button { padding: 0.6rem 1.5rem; background: #10b981; color: #fff; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; }
#status { margin-top: 1rem; font-size: 0.875rem; }
</style>
</head>
<body>
<h1>Join the waitlist</h1>
<form id="waitlist-form">
<label for="email">Email</label>
<input id="email" type="email" name="email" placeholder="you@example.com" required />
<label for="name">Name</label>
<input id="name" type="text" name="name" placeholder="Your name" />
<!-- Honeypot: bots fill this, humans don't see it -->
<input name="website" type="text" style="display:none" tabindex="-1" aria-hidden="true" />
<button type="submit">Join waitlist</button>
</form>
<p id="status"></p>
<script>
const form = document.getElementById("waitlist-form");
const status = document.getElementById("status");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const data = Object.fromEntries(new FormData(form));
const res = await fetch(
"https://forms.devxgroup.io/api/v1/submit/waitlist",
{
method: "POST",
headers: {
"x-api-key": "fr_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}
);
const json = await res.json();
if (json.ok) {
status.textContent = "You're on the list. Check your email.";
form.reset();
} else {
status.textContent = json.error?.message ?? "Something went wrong.";
}
});
</script>
</body>
</html>Keep your API key out of client-side code in production. The safest pattern is a thin server-side proxy that injects the key and forwards the body to form-relay.