Form spam checks as one API call.

POST /v1/check: real submissions and how Doorman judged them
-
Specimen · kind: leadNº 106759 0000
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 · kind: leadNº 108436 7619
From partnerships@growthlane.io
“Loved your pricing page. We help SaaS teams like yours book 30+ demos a month with done-for-you outbound. Worth a quick call?”
pitch
3% chance it’s real · 91 ms
Void -
Specimen · kind: signupNº 110114 5238
From xkq93jd8s2@mailinator.com
“asdf asdf · xkq93jd8s2@mailinator.com”
fake_account
4% chance it’s real · 108 ms
Void -
Specimen · kind: leadNº 111792 2857
From ops@harbourfreight.example
“We send about 400 invoices a month across three entities. Does your plan cover multi-entity, and can we start before quarter end?”
95% chance it’s real · 85 ms
Genuine -
Specimen · kind: leadNº 113470 0476
From sales@devsquad.example
“Saw you're hiring engineers. Our nearshore team can ship your roadmap at half the cost. Free for a call Thursday?”
pitch
3% chance it’s real · 90 ms
Void -
Specimen · kind: leadNº 115147 8095
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
Sound familiar?
POST a submission and get back deliver, hold or drop, with a probability and the evidence, in about 100 ms. Node SDK, Python, Ruby and Elixir examples, signed webhooks, an MCP server, and a setup guide your coding agent can follow.
14 days of Pro free, no card. Then free for 100 submissions a month, or Pro from $29.
- Rolling your own means rules foreverHoneypots, timers and regex lists catch last year's bots and none of this year's humans, and someone has to maintain them.
- Captcha libraries tax every real userThey add friction to your conversion path and still let paid spammers through.
- Keyword filters miss written pitchesSpam filters match what they have seen before. A polite, hand-written pitch from a real person sails through, and that is most of what reaches a contact form now.
An endpoint, not a project
- One request form id or kind, the fields you have, optional signals. Response: route, action, p_real, reason, evidence.
- Fails open the SDK returns hold on timeouts and network errors, so an outage never loses a submission.
- Webhooks signed with HMAC-SHA256 and retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours.
- Agents and MCP /llms.txt, a signup API and a remote MCP server, so Claude Code, Codex or Cursor can wire it up for you.
curl https://withdoorman.com/v1/check \
-H "Authorization: Bearer $DOORMAN_KEY" \
-H "Content-Type: application/json" \
-d '{"form": "f_yourForm", "email": "jess@brightline.co",
"message": "We send 200 invoices a month. Demo?"}'
# {"route": "deliver", "action": "deliver", "p_real": 0.97,
# "reason": null, "evidence": "We send 200 invoices a month.", "latency_ms": 79}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, no batch job
- 0.992
- precision on 1,956 human-labelled comments from a public spam benchmark
Latency from 104 live checks on our labelled test set. Benchmark: the UCI YouTube Spam Collection, recall 0.980, 8.8% held for a person; questions were not tuned to it.
Questions
What are the rate limits?
600 API requests a minute per account. Hosted form endpoints accept 30 posts a minute per IP per form; beyond that submissions are stored as held rather than rejected.
What happens on a timeout?
The @withdoorman/client SDK returns action hold with reason doorman_unreachable instead of throwing, so the submission is kept for review. With plain HTTP, treat any error the same way.
Which languages are supported?
Anything that can make an HTTPS request. There's a Node SDK with TypeScript types, and ready-made Python, Ruby, Elixir, Express and Next.js snippets from the snippet API.
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 forms.
Start with 14 days of Pro, free. Turn on watch mode to see every call before you trust it.
