SpamFlip

Formspree

Last updated October 19, 2026. SpamFlip is operated by MLN Learning LLC.

Formspree's HTML form article says a form needs an action set to that form's endpoint, and that each field you want sent needs a name. The endpoint is on the Integration tab, under “Your form's endpoint is”. Their hash id article shows the same place, and the Overview tab after the first submission. The endpoint they show in the spam article looks like https://formspree.io/f/a_form_id.

Do not put an email address in the action. Formspree's legacy forms article calls https://formspree.io/your@email.com a legacy form and says they are removing support for it.

Markup

Mark the form with data-spamflip and method="POST". The snippet only attaches to form[data-spamflip]. Replace both placeholders. The HTML forms page describes the rest of the snippet.

<script src="https://spamflip.app/sf.js" data-site-key="YOUR_SITE_KEY" defer></script>

<form data-spamflip action="https://formspree.io/f/YOUR_FORM_ID" method="POST">
  <input name="email" type="email" />
  <textarea name="message"></textarea>
  <button type="submit">Send</button>
</form>

Save https://formspree.io/f/YOUR_FORM_ID as the site's forward URL in the dashboard. That saved URL is what SpamFlip calls. The form action is not read as the forward address. The action is used only if the browser cannot complete the request to SpamFlip twice. Each of those tries waits up to 12 seconds. The honeypot fields are removed before that fallback submit.

The request SpamFlip sends

On a clean verdict, and when the submission has no file upload, the server POSTs the string fields to the saved URL. The method is POST. The content type is application/x-www-form-urlencoded. Each field keeps the name from the form. Accept is application/json. sf_hp, sf_site, sf_field_to_submit_ms, sf_fill_velocity_ms, sf_mouse_moved, sf_token, and the rotating honeypot name are removed. File inputs are not included. The server stops waiting after 8 seconds. A quarantine or spam verdict is not forwarded. A response that is not successful stays on the page. The snippet does not then submit the form to Formspree.

The browser snippet always sends the form to SpamFlip as multipart FormData. The URL-encoded body above is the request SpamFlip sends when that form has no file. A submission that includes a file is still POSTed as multipart form data, with the same Accept header, and the file bytes are not copied into that request.

If the handler responds with 301, 302, or 303, SpamFlip counts the delivery as successful. It does not POST the fields again, and it does not request the redirect location. The visitor then receives HTTP 200 and the JSON body {"status":"ok"}. A 307 or 308 is repeated as the same POST, body included, at that location. Any other redirect status is requested again with GET and no body. At most two redirects are followed. A followed target that is not a public https address fails the delivery.

Formspree's HTML form article describes a browser form posting to the endpoint. It says submissions from that form are stored in the Formspree account. That sentence is about Formspree's own form post. This page does not claim that Formspree stores the URL-encoded POST SpamFlip sends, and it does not claim that a file upload, a plugin, or a plan feature is available. A check with a Formspree account has not been run.