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.