Forms

A form endpoint for your site, with spam filtering, double opt-in and delivery built in.

Forms gives each form on your site an endpoint to post to. You don't need a backend: a plain HTML <form> posts to it, Risk screens every submission, and accepted ones go to your webhooks, to your team by email and into your contacts. It uses the same API key, logs and sandbox environments as everything else.

const { :  } = await ..({
  : "Contact us",
  : ["https://www.example.com"],
  : { : ["support@example.com"] },
});
// form?.endpoint: https://…/f/form_01k…

Then point your form at its endpoint:

<form action="https://…/f/form_01k…" method="post">
  <input type="email" name="email" required>
  <textarea name="message"></textarea>
  <!-- The honeypot: people leave it empty, bots fill it in. -->
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button>Send</button>
</form>

You can also create forms in the dashboard: each environment's Forms page shows the snippet to paste.

What happens to a submission

  1. The form checks it. The form must be enabled and the post must come from one of its allowed_origins (if it lists any). With fields defined, every value is validated against them.
  2. Risk screens it. The honeypot, then a Risk assessment of the submitter's email, IP, browser, captcha and the text they wrote. A submission Risk refuses is spam; one it wants reviewed is held.
  3. It is delivered. An accepted submission sends form.submission.received to your webhooks, emails the form's recipients and adds the submitter to your contacts (destinations). With submitter.verify, it first waits until the submitter clicks the link emailed to them (double opt-in).

Spam is answered exactly like a success, so nothing tells a bot what tripped it. You see it on the form's Spam tab and can release it (coss.forms.submissions.release).

Accepted submissions are kept for 90 days; spam, held and unconfirmed ones for 14 days.

What's in it