Spam checks for your Next.js forms, in one call.

Next.js API route: real submissions and how Doorman judged them
-
Specimen · POST /api/contactNº 067131 0029
From zara@quill.example
“I run Quill Legal. We use Xero today. Half our clients are in the UK. Can we get a demo this week?”
91% chance it’s real · 87 ms
Genuine -
Specimen · POST /api/contactNº 065453 2410
From hello@scaleleads.co
“Are you accepting guest posts? I have a well researched article on small business cash flow that fits your audience.”
pitch
2% chance it’s real · 83 ms
Void -
Specimen · POST /api/contactNº 063775 4791
From maria.gonzalez@brightlinedental.com
“Maria Gonzalez · Brightline Dental”
83% chance it’s real · 92 ms
Genuine -
Specimen · POST /api/contactNº 062097 7172
From xkq93jd8s2@mailinator.com
“asdf asdf · xkq93jd8s2@mailinator.com”
fake_account
4% chance it’s real · 108 ms
Void -
Specimen · POST /api/contactNº 060419 9553
From kofi@proton.me
“I run Brightline Dental. Clients keep asking to pay by card and we can't take it. Does it import from what we use now?”
81% chance it’s real · 78 ms
Genuine -
Specimen · POST /api/contactNº 058742 1934
From t54ywc@yopmail.com
“Hello https://example.com/, Get 1000 free visitors to your website today! Click here: http://bit.ly/tr4ff1c”
Spam
1% chance it’s real · 84 ms
Void
Sound familiar?
Call Doorman from your route handler or server action before you save the lead or send the email. You get deliver, hold or drop in about 100 ms, with a plain-language reason attached.
14 days of Pro free, no card. Then free for 100 submissions a month, or Pro from $29.
- Captchas cost you conversionsA challenge on your contact form is friction right where a buyer is reaching out, and it doesn't read what people send.
- Rolling your own filter never endsWord lists, disposable-domain lists and rate limits catch last month's spam and block this month's customers.
- Fake sign-ups skew everythingThrowaway accounts inflate trials, burn onboarding emails and make activation numbers meaningless.
Add it to a route handler
- Install npm i @withdoorman/client, then put DOORMAN_KEY in your environment.
- Check before you act save the lead, create the account or capture the order only when the action isn't drop.
- Fails safe a timeout or network error returns hold, not an exception, so nothing real is lost.
- Or skip the code point a plain form's action at the hosted URL, or let your coding agent set it up from one prompt.
import { Doorman } from "@withdoorman/client";
const doorman = new Doorman(process.env.DOORMAN_KEY!);
export async function POST(req: Request) {
const f = await req.formData();
const r = await doorman.check({
form: "f_yourForm",
email: String(f.get("email") ?? ""),
message: String(f.get("message") ?? ""),
});
if (r.action !== "drop") await saveLead(f, { review: r.action === "hold" });
return Response.json({ ok: true }); // same answer for everyone
}Checked, not guessed.
Every decision comes from Doorman's models reading the submission, in milliseconds, with the reason attached.
- ~100 ms
- to judge a submission
- 1
- request per submission: no queue, no polling
- 0
- genuine submissions dropped in our labelled contact-form set
Labelled test set: 104 invented but labelled contact-form and checkout submissions, judged live; latency is the median of those checks. Questions were not tuned to the set.
Questions
Does it work with server actions?
Yes. Call doorman.check from the server action exactly as in the route handler; it only needs the key on the server.
Is there a client-side script?
No. Doorman runs on your server or as the form's action URL, so nothing is added to your pages.
Can it check sign-up forms too?
Yes: pass kind signup and it looks for throwaway and fake accounts as well as spam.
How much does it cost?
Free for 100 submissions a month. Pro is $29 a month for 5,000 and Business is $79 a month for 50,000, and every account starts with 14 days of Pro. Until November 30, the first 100 paying customers get Pro at $19 and Business at $59, kept for as long as they stay. See pricing.
Try it on your own Next.js form.
Start with 14 days of Pro, free. Turn on watch mode to see every call before you trust it.
