Point any HTML form at one endpoint. 500 free submissions — no card, no time limit — and unlimited forms.
Create free accountA honeypot field is a form input that real visitors never see and spam bots fill in, so the server can throw away any submission where it arrives with a value. It is about as cheap as spam filtering gets: one extra input, one line of server logic, nothing for visitors to solve. This page covers how it works, the HTML, what to name it, the autofill mistake that cost us real signups, and how it compares with a time-trap and a CAPTCHA.
Last reviewed against the splitforms submit endpoint and its spam rules.
How does a honeypot field work?
A honeypot works because many spam bots never look at the page the way a person does. They fetch the HTML, find the <form>, put a value in every input, and post it. A person only fills the fields they can see. So:
- You add one extra input and hide it with CSS.
- A visitor fills the visible fields and submits. The hidden field arrives blank.
- A bot fills everything, including the hidden field, and submits. It arrives with a value.
- The server checks that one field. Blank: handle the submission. Anything else: discard it but still answer with a success response, not an error, so the bot's author has nothing to debug.
On splitforms, step 4 is already done. The submit endpoint checks botcheck, _gotcha, hp, honey, trap, do_not_fill and leave-blank. If any of them arrives non-blank, the submission isn't stored, emailed, sent to integrations or counted toward your plan, and the bot gets HTTP 200 with {"success": true}.
What does a honeypot field look like in HTML?
A honeypot is an ordinary text input, wrapped so that people, keyboards, screen readers and password managers all skip it. Here is a complete contact form with one, posting to splitforms:
<form action="https://splitforms.com/api/submit" method="POST">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<!-- Honeypot: off-screen, out of the tab order, ignored by
screen readers and password managers -->
<div class="hp" aria-hidden="true">
<label for="botcheck">Leave this empty</label>
<input type="text" id="botcheck" name="botcheck"
tabindex="-1" autocomplete="off"
data-1p-ignore data-lpignore="true"
data-bwignore="true" data-form-type="other" />
</div>
<input type="text" name="name" autocomplete="name" placeholder="Your name" required />
<input type="email" name="email" autocomplete="email" placeholder="Your email" required />
<textarea name="message" placeholder="Your message" required></textarea>
<button type="submit">Send</button>
</form>And the CSS, in your stylesheet rather than inline:
.hp {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}If you run your own backend, the server side is a few lines. In Node with Express:
app.post("/contact", express.urlencoded({ extended: false }), (req, res) => {
const trap = String(req.body.botcheck ?? "").trim();
if (trap !== "") {
// A bot filled the honeypot: save nothing, send nothing,
// and answer with a success, not an error.
return res.status(200).json({ success: true });
}
// ...validate, store and email the real submission
res.json({ success: true });
});Want the markup without typing it? The honeypot field generator builds it for you, and the contact form spam checker reads your existing form HTML and tells you whether a honeypot is there.
What should you name a honeypot field?
Name a honeypot something no browser or password manager would recognize as a real field. If you use a form backend, pick one of the names it checks. On splitforms that is botcheck, _gotcha, hp, honey, trap, do_not_fill and leave-blank; any other name is delivered to you as an ordinary field, not dropped.
Older advice says to use tempting names like website or confirm_email because bots love to fill them. Browsers and password managers love them too. Avoid these as trap names:
website, url, company, company_website, organization, email2, confirm_email, phone2, address.
This is also why splitforms never treats those names as honeypots: plenty of real forms ask for a company website or a confirm-email field, and dropping those submissions would lose genuine leads.
Can autofill or a password manager trip a honeypot?
Yes. Autofill and password managers fill fields by name and label, not by whether you can see them, so a hidden field that looks like a company or website field can be filled for a real visitor. The server then sees a filled trap and drops a genuine submission, and nobody is told.
company_website. Browser autofill and password managers filled it for some real people despite autocomplete="off", so they saw "code sent" and never got a code. We fixed it on September 27, 2026 by renaming the field hp_field, labelling it "Leave this empty", and adding password-manager opt-out attributes.autocomplete="off" is not a guarantee: MDN's guide to turning off form autocompletion notes that many modern browsers ignore it for login fields. To keep a honeypot safe from autofill:
- Use a name and label that match no autofill category.
botcheckwith the label "Leave this empty" is safe;company_websitewith the label "Company website" is not. - Add the opt-out attributes. 1Password documents
data-1p-ignorefor fields it should ignore. Our sign-up form also carriesdata-lpignore,data-bwignoreanddata-form-type="other"for LastPass, Bitwarden and Dashlane. - Test with your own autofill on. Fill the form with your saved profile and password manager, then check the trap is still empty before you submit (see the test steps below).
How should you hide a honeypot field?
Hide a honeypot with CSS, not with type="hidden". From weakest to strongest:
type="hidden": don't. Bots treat hidden inputs as tokens to send back unchanged, so they rarely fill them. Use hidden inputs for things like your access key.- Inline
style="display:none": works. Bots that never apply CSS fill it. A slightly smarter script can read the inline style and skip the field. - A class in your stylesheet: better. The script now has to fetch and parse your CSS to know the field is hidden.
- Off-screen positioning: best.
position: absolute; left: -9999pxnever says "hidden" or "none"; only a bot running a real layout engine can tell.
The one-line snippets in the splitforms docs use an inline display:none checkbox named botcheck for brevity. It catches the same fill-everything bots; the off-screen version above is a small upgrade if you want one.
Honeypot vs time-trap vs CAPTCHA: what's the difference?
A honeypot checks what was filled in, a time-trap checks how fast it was filled in, and a CAPTCHA asks a third-party service who filled it in. The first two are invisible and free; a CAPTCHA catches more capable bots at the cost of a vendor script and, sometimes, a challenge for the visitor.
We haven't found an independent, published head-to-head block rate for these three, so the table compares how they work rather than quoting percentages. Most forms should start with a honeypot plus a time-trap and add a CAPTCHA only if spam still gets through. For the CAPTCHA side, see honeypot vs reCAPTCHA and adding Cloudflare Turnstile to an HTML form.
What can't a honeypot catch?
A honeypot only catches bots that fill a field they can't see. It is blind to:
- Browser-based bots. Bots built on a real browser engine apply your CSS and fill only the visible fields.
- Bots written for your form. Someone who inspects your form once can leave the trap blank forever.
- Spam sent by people. Paid spammers, and pitches written by a language model and pasted into the real form, leave the trap empty.
- The content itself. A bot that leaves the trap empty can still stuff the message with links.
That is why a honeypot is the first layer, not the only one. Add a time-trap for bots that submit instantly, rate limits for repeat senders, and checks on the message content. The server-side spam protection checklist walks through each layer.
How do you test a honeypot field?
Test a honeypot in three passes, and only trust it once all three behave:
- Normal submit. Fill the visible fields and send. The submission should arrive.
- Bot submit. In your browser's console, run
document.querySelector('[name="botcheck"]').value = "bot", then send. You should get a success response, and nothing should arrive in your inbox or dashboard. On splitforms, a plain HTML form shows{"success": true}instead of your thank-you page, which is how you know the trap fired. - Autofill submit. Fill the form with your browser's saved details and your password manager, then run
document.querySelector('[name="botcheck"]').valuein the console before you send. It must return an empty string.
For the rest of the pre-launch checks, see how to test a contact form.
Does splitforms check the honeypot for you?
Yes. splitforms checks honeypot fields server-side on every form, on every plan, with no code on your side beyond the hidden input. It is one layer of smart spam filtering:
- Honeypot: botcheck, _gotcha, hp, honey, trap, do_not_fill and leave-blank, on by default with a per-form toggle.
- Time-trap: send
form_loaded_atand submissions made under 2 seconds or over 24 hours after page load are dropped. - Rate limits: per visitor IP and form, 6 submissions a minute and 20 per 15 minutes.
- Content checks: rule-based content scoring (links, spam phrases, disposable email domains, gibberish) moves suspect submissions to a Spam folder you can review, instead of deleting them.
- Optional CAPTCHA: Cloudflare Turnstile and Google reCAPTCHA v2 tokens are verified once you save your secret key.
Free covers 500 submissions in total with no card and no time limit; Pro is $5 per month. Create a free account, paste the form above with your access key, and the honeypot works on the first submission. More on the full filter on the spam-free contact form page.
FAQ
Why is it called a honeypot?
The name comes from security research, where a honeypot is a decoy, such as a fake server or account, set out so attackers reveal themselves by touching it. A honeypot form field is the same idea in miniature: the hidden input is bait, and a bot that fills it has identified itself.
Will a honeypot field block real visitors?
Only if something fills the trap for them. Browser autofill and password managers can fill a hidden field that is named like a real one (company, website, email2), even with autocomplete="off", and that submission is then dropped without anyone noticing. Give the trap a name no autofill category matches, add password-manager opt-out attributes such as data-1p-ignore, and test the form with your own autofill turned on.
Should a honeypot use type="hidden"?
No. Bots treat type="hidden" inputs as tokens to send back unchanged, so they rarely fill them and the trap catches nothing. Use an ordinary text input and hide it with CSS. Off-screen positioning from a stylesheet is the hardest for a script to spot; inline display:none also works against bots that never apply CSS.
Is a honeypot field accessible?
Yes, when it is hidden properly. Wrap it in an element with aria-hidden="true" so screen readers skip it, give the input tabindex="-1" so keyboard users can't tab into it, and label it "Leave this empty" as a fallback for anyone who still reaches it.
Should the server return an error when the honeypot is filled?
No. Return a success response and simply don't save or send anything. An error message tells the bot's author which field to skip next time. splitforms answers a filled honeypot with HTTP 200 and {"success": true}.
Do honeypots stop AI-written spam?
Not on their own. A message written by a language model and submitted through the real form, by a browser or a person, leaves the hidden field empty. Catching it takes checks on the content itself: links, spam phrases, disposable email domains and gibberish. splitforms runs rule-based content scoring for this and moves suspect submissions to a Spam folder you can review.
Do I need server code for a honeypot on splitforms?
No. Add one hidden input named botcheck (or _gotcha, hp, honey, trap, do_not_fill or leave-blank) and the submit endpoint drops any submission where it is filled. It works on every plan, including Free (500 submissions total, no card). Pro is $5 per month.
Keep going on spam defense: stop contact form spam, the complete spam protection guide, a contact form without CAPTCHA, and the splitforms security page.