---
title: "Plain HTML form"
description: "Post a plain HTML form to your form address, with one script line for the bot check. A hidden _next field sends visitors to your own page."
url: "https://formparcel.live/docs/guides/html"
---

# Plain HTML form

Post a plain HTML form to your form address, with one script line for the bot check. A hidden _next field sends visitors to your own page.

Untested: Not yet tested on a live site. The steps follow how the form address works today; if one differs, [tell us](https://formparcel.live/contact).

## The form

Set the form’s `action` to your form address and its `method` to `POST`. Keep your own markup and styling. The dashboard gives you this snippet with your address filled in.

Example form address. Use yours from the dashboard.

```html title="contact.html"
<form action="https://f.formparcel.live/f/f_k7QmXp2aVb9sTn4cLw8RhE" method="POST" onsubmit="if(!window.FormParcel){event.preventDefault();var f=this;f.setAttribute('data-fp-wait','1');setTimeout(function(){if(f.getAttribute('data-fp-wait')){f.removeAttribute('data-fp-wait');HTMLFormElement.prototype.submit.call(f)}},10000)}">
  <!-- Spam trap: people never see it, bots fill it in. Keep it hidden. -->
  <div aria-hidden="true" style="position:absolute;left:-10000px;">
    <input type="text" name="_gotcha" tabindex="-1" autocomplete="off">
  </div>

  <!-- Optional: send visitors to your own thank-you page. -->
  <input type="hidden" name="_next" value="https://your-site.example/thanks">

  <label for="name">Name</label>
  <input type="text" id="name" name="name" required>

  <label for="email">Email</label>
  <input type="email" id="email" name="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" required></textarea>

  <button type="submit">Send</button>
</form>
<!-- FormParcel bot check: no cookies, no widget. Without it, submissions wait in your Spam folder. -->
<script src="https://f.formparcel.live/f/formparcel.js" async></script>
```

| Attribute | Value | Notes |
| --- | --- | --- |
| `action` | Your form address | Copy it from the form’s page in the dashboard. It does not change. |
| `method` | `POST` | Only POST is accepted. A GET request is answered with [405](https://formparcel.live/docs/reference/responses#method-not-allowed). |
| `enctype` | Leave it unset, or `multipart/form-data` | The default encoding works. `multipart/form-data` is accepted for text fields only. |

## Field names

A field is sent only if it has a `name`. Each name becomes a column in the Sheet. If a form starts sending a name the Sheet has no column for, the lead is saved and waits as New fields to review. Nothing is dropped, and nothing is written to the Sheet until you review the new field in the dashboard. There you can add it as a column, or ignore it, for example a field a spam bot made up. An ignored field is left out of the Sheet, the lead keeps it, and you can stop ignoring it later in the form’s settings.

When several fields share a name, for example a group of checkboxes, their values are stored together as one value.

## The spam trap

`_gotcha` is a field people should never see. Bots tend to fill in every field they find. If it arrives with any value, FormParcel drops the post: nothing is saved and no receipt is created. Hide the field by moving it off-screen, as the snippet does, and keep `tabindex="-1"` and `autocomplete="off"` on it so keyboards and password managers skip it.

## The bot check

The script line after the form is FormParcel’s bot check:

```html title="After the form"
<script src="https://f.formparcel.live/f/formparcel.js" async></script>
```

It does a short piece of work in the visitor’s browser and adds a hidden `_fp_proof` field to the form. It sets no cookies and shows nothing. Keep it on every page that has the form. Without it, or with JavaScript turned off, the form still posts and the lead is saved, but it waits in your Spam folder until you release it with **Not spam**. If the site has a Content-Security-Policy, allow the form endpoint host in `script-src` and `connect-src`. How it works is on [Spam protection](https://formparcel.live/docs/setup/spam-protection#the-bot-check).

For a stronger check, a client site can turn on Cloudflare Turnstile: [spam protection](https://formparcel.live/docs/setup/spam-protection). The trap’s name, and what a script or a browser gets back when it is filled, are on [special fields](https://formparcel.live/docs/reference/fields#trap-field).

> **Bot check.** A lead sent without FormParcel's bot check is saved but held in your Spam folder, not delivered. That is every post from a server, a webhook or `curl`, and every post from a page that does not load the script. The dashboard then shows **Bot check not installed** under Needs action. Fix: keep the script line on every page that has the form. [Learn more](https://formparcel.live/docs/reference/bot-check)

## Your own thank-you page

Add a hidden `_next` field with the full address of a page on the client’s own site. After the lead is saved, FormParcel redirects the visitor there. Without it, the visitor sees a short FormParcel confirmation page. FormParcel only follows an address it can trust, and the rule is on [special fields](https://formparcel.live/docs/reference/fields#redirects).

## What the visitor sees

A browser form post gets one of two things: a redirect to a trusted `_next`, or a short, neutral FormParcel page such as “Your message was sent”, or a plain explanation when something went wrong. Neither shows the receipt ID, and each page has a “Report abuse” link to our [contact page](https://formparcel.live/contact). Anything that is not a browser form post gets JSON instead: [the fetch guide](https://formparcel.live/docs/guides/fetch). Every answer is on [Responses and error codes](https://formparcel.live/docs/reference/responses).

## What is not accepted

- File inputs. A file in the post is refused ([`FILE_UPLOAD_NOT_SUPPORTED`](https://formparcel.live/docs/reference/responses#file-upload-not-supported)), so leave them out of the form.
- Fields named like a password or a card detail. They are refused ([`PROHIBITED_FIELD`](https://formparcel.live/docs/reference/responses#prohibited-field)).
- A post with no readable value in any field ([`EMPTY_SUBMISSION`](https://formparcel.live/docs/reference/responses#empty-submission)).

The limits on size and fields are on [Limits and retention](https://formparcel.live/docs/reference/limits).

## Check it

Send a test lead from the form’s page in the dashboard, then post the form once from the client’s site and open its receipt under **Leads**. If nothing arrives, go through [Troubleshooting](https://formparcel.live/docs/help/troubleshooting).
