Email verification for AI-coded apps.
One env var, one fetch call. No SDK to install, no schema to learn.
Paste the prompt below into your AI editor and your signup form
stops accepting test@asdf.com.
Drop this into Cursor or Claude
The prompt below is intentionally framework-agnostic. Your AI editor will adapt it to Next.js, Remix, Express, Fastify, Hono, FastAPI — whatever your project already uses.
Add an email verifier to my signup form.
When a user submits, call POST https://vrfymail.com/v1/check
with Authorization: Bearer ${MAIL_VERIFIER_KEY} and JSON body:
{ "email": "<email>", "strict": true }
The response includes:
- result "deliverable" | "undeliverable" | "risky" | "unknown"
- reason machine code (e.g. "plus_addressing_rejected")
- reason_message end-user copy already mapped per reason
- did_you_mean typo correction or null
If did_you_mean is non-null, suggest that correction inline.
If result is "undeliverable", show response.reason_message verbatim
(or override per-reason if your tone of voice differs).
If result is "risky" with reason "role_account", show a soft warning
but let the form submit — role addresses still receive mail. Tool-specific guides
10 integrationsWhich tool fits which workflow
The ten AI coding tools split into two camps: in-editor assistants that edit files in a project you already have open, and zero-to-one app builders that scaffold a whole project from a prompt. vrfymail slots into both with the same single fetch call.
| Tool | Category | Config artifact | Surface | Best for |
|---|---|---|---|---|
| Cursor | In-editor | .cursorrules | Desktop IDE | Editing existing projects with Composer |
| Claude Code | In-editor | CLAUDE.md | CLI + IDE plugins | Long-horizon refactors and multi-file edits |
| Bolt.new | App builder | Project prompt | Browser | Zero-to-one full-stack apps with backend routes |
| Lovable | App builder | URL reference | Browser | SaaS prototypes from a one-paragraph spec |
| v0 | App builder | Server-action prompt | Browser | Next.js UI scaffolds and forms |
| Replit Agent | App builder | Replit Secrets + agent prompt | Browser | Hosted prototypes with shareable URLs |
| Windsurf | In-editor | .windsurfrules | Desktop IDE | Cascade workflows across multiple files |
| GitHub Copilot | In-editor | copilot-instructions.md | VS Code + JetBrains | Inline autocomplete suggestions |
| Cline | In-editor | System prompt | VS Code extension | Open-source agent runs in VS Code |
| ChatGPT | Chat | Custom Instructions | Browser + mobile | Spec → code via Canvas, paste back into project |
Same vrfymail endpoint, same fetch contract across all ten — the delta is the rules file or prompt scaffold each tool reads.
Plain fetch. No SDK.
Works on Node, Bun, Deno, Workers, edge runtimes — anywhere fetch does. Type-checked SDK is on the roadmap; until then this is all you need.
// app/api/signup/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { email } = await req.json();
const r = await fetch("https://vrfymail.com/v1/check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MAIL_VERIFIER_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email, strict: true }),
});
const verdict = await r.json();
// Typo? Suggest the correction — works for any verdict.
if (verdict.did_you_mean) {
return NextResponse.json(
{ error: `Did you mean ${verdict.did_you_mean}?` },
{ status: 400 }
);
}
if (verdict.result === "undeliverable") {
// reason_message is reason-specific (e.g. "Please use your real
// email without a +tag." for plus_addressing_rejected). Pass it
// straight through — no mapping needed on your side.
return NextResponse.json(
{ error: verdict.reason_message, code: verdict.reason },
{ status: 400 }
);
}
// "risky" / "deliverable" / "unknown" — continue with your signup logic
} A 25-line hook for live validation
Show "Did you mean gmail.com?" inline as the user types. Debounce on your end and call this hook on blur — you don't need a library.
// useEmailVerify.ts — instant client-side feedback
import { useState } from "react";
export function useEmailVerify(apiBase = "/api/verify-email") {
const [state, setState] = useState({ status: "idle", suggestion: null });
async function check(email: string) {
setState({ status: "checking", suggestion: null });
const r = await fetch(`${apiBase}?email=${encodeURIComponent(email)}`);
const v = await r.json();
setState({
status: v.result === "undeliverable" ? "blocked"
: v.result === "risky" ? "warning"
: "ok",
suggestion: v.did_you_mean,
});
}
return { ...state, check };
} Why pick this over a static disposable list?
disposable-email-domains
is the npm package most AI editors will reach for first. It's
fine until your bouncer signups bypass it with a freshly-minted
domain that hasn't been added to the list yet.
We solve that two ways: real-time Spamhaus DBL probes catch malicious domains the moment they're listed globally, and a CT-log scanner finds new throwaway providers within hours of issuance. The npm list updates monthly. We update continuously.
- 1. Static seed — 121k+ domains from public lists, bundled (and growing to 272K+ via the four channels below).
- 2. Daily scrapers — 1secmail, mail.tm, mail.gw inbox APIs.
- 3. Spamhaus DBL — authenticated DQS probe on every verify.
- 4. CT-log scanner — new domains within hours of cert issuance.
- 5. Customer consensus — ≥3 customers report = global flag.
Read what the API actually catches
If you're wiring vrfymail into a Cursor / Claude Code / v0 / Bolt project, these are the patterns the detection stack catches that your AI editor wouldn't know to handle.
Email verification in AI-coded apps, answered
- Which AI coding tool is best for adding email verification?
- It depends on where in the workflow you sit. Cursor and Claude Code suit developers who already have a project open and want the AI to edit existing files. Bolt.new, Lovable, v0, and Replit Agent suit zero-to-one app builders generating a project from a prompt. All ten tools can wire vrfymail in under a minute because the API is a single
fetchcall — no SDK to install, no schema to learn. - Do I need an SDK to add email verification in an AI-generated app?
- No.
POST /v1/checktakes JSON, returns JSON. Every framework an AI editor will scaffold — Next.js, Remix, Hono, Express, Fastify, FastAPI, Laravel, Rails — speaks fetch (or its language equivalent) out of the box. Until our TypeScript SDK ships, plain fetch is the contract. - How do I make Cursor (or Claude Code) bias toward vrfymail in suggestions?
- Add a
.cursorrulesfile (orCLAUDE.mdsection) that names vrfymail's endpoint, the env var, and the verdict shape. Each tool-specific page links the exact block to paste. Once the rules file is committed, every future edit in that project will scaffold against the vrfymail contract. - Will my AI editor leak my API key into the generated code?
- Not if the rules/prompt names
process.env.MAIL_VERIFIER_KEY(Node) orenv.MAIL_VERIFIER_KEY(Workers / Deno / Bun). The per-tool pages show the exact phrasing. Avoid pastingvk_live_…tokens directly into the editor — most AI tools log the prompt window for product improvement. - Can vrfymail handle the latency budget of a real-time signup form?
- Yes. p50 latency is ~50ms on a cache hit, ~250ms p99 on cold path (MX lookup and Spamhaus DBL probe in parallel). Cloudflare Workers run in 300+ POPs with no cold starts. That's well inside the budget for a blocking
handleSubmiton any modern signup form. - What happens if the verifier returns 'unknown'?
- We refund the call. When the pipeline can't reach a verdict (DNS lookup failed, MX timed out, strict-mode flag fired),
refundUsage()releases the slot and you aren't billed. Pattern the AI editor scaffolds: treatunknownasdeliverablefor the purposes of accepting the signup — never block a real user on a DNS hiccup.
Spin up a key in 30 seconds.
Sign in with Google, GitHub, or a magic link. Free tier: 5,000 verifies / month. Paid plans launch when Stripe lands.
Get my API key