Email check
Check one email address for throwaway domains, typos, missing mail servers, new domains, role inboxes and (optionally) the mailbox itself.
POST /v1/email/check · 1 credit (+5 with verify_mailbox)
Request
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | yes | The address to check. |
verify_mailbox |
boolean | no | Also ask the domain's mail server whether this mailbox exists. Adds up to a few seconds and 5 credits. Charged only if the server was actually asked. Default false. |
curl https://veqen-app.com/v1/email/check \
-H "Authorization: Bearer $VEQEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "jane.doe+promo@gmial.com"}'
r = requests.post(
"https://veqen-app.com/v1/email/check",
headers={"Authorization": f"Bearer {VEQEN_API_KEY}"},
json={"email": "jane.doe+promo@gmial.com"},
timeout=10,
)
const r = await fetch("https://veqen-app.com/v1/email/check", {
method: "POST",
headers: { Authorization: `Bearer ${VEQEN_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ email: "jane.doe+promo@gmial.com" }),
});
You can also use GET /v1/email/check?email=... for quick tests. Prefer POST in production so addresses don't end up in URL logs.
Response
Typo domains like this are often registered by throwaway services, so this one is both a typo and disposable:
{
"email": "jane.doe+promo@gmial.com",
"valid_syntax": true,
"normalized": "jane.doe+promo@gmial.com",
"canonical": "jane.doe@gmial.com",
"local_part": "jane.doe+promo",
"domain": "gmial.com",
"disposable": true,
"free_provider": false,
"role_account": false,
"plus_addressed": true,
"did_you_mean": "jane.doe+promo@gmail.com",
"domain_info": {
"exists": true,
"accepts_mail": true,
"mx": [],
"null_mx": false,
"spf": false,
"dmarc": false,
"registered_at": "2003-05-12",
"age_days": 8562,
"registrar": "GoDaddy.com, LLC"
},
"mailbox": null,
"risk": {
"score": 93,
"level": "high",
"verdict": "refuse",
"reasons": [
{ "code": "disposable_domain", "impact": 90, "message": "gmial.com hands out throwaway inboxes." },
{ "code": "possible_typo", "impact": 30, "message": "Looks like a typo of gmail.com." },
{ "code": "plus_addressed", "impact": 5, "message": "Uses a +tag, so one inbox can sign up many times." }
]
}
}
Fields
| Field | What it tells you |
|---|---|
valid_syntax |
false means it isn't an email address at all. syntax_error then explains why. |
normalized |
The address with a lower-cased, standard domain. |
canonical |
The inbox it really lands in: +tags removed, and for Gmail, dots removed too. Compare this to spot one person making many accounts. |
disposable |
The domain hands out throwaway inboxes (Mailinator, 10 Minute Mail and thousands more). |
free_provider |
A consumer mailbox like Gmail or Outlook. Normal for people, unusual for a B2B signup. |
role_account |
A shared inbox such as info@ or support@. |
plus_addressed |
The address has a +tag. |
did_you_mean |
A suggested fix for a likely typo. Show it: "Did you mean jane@gmail.com?" |
domain_info.accepts_mail |
Whether mail can be delivered to the domain: it has MX records, or (as the email standard allows) an address record to fall back on. false means mail can never arrive. null means DNS couldn't be reached. |
domain_info.mx |
Mail servers, most preferred first. |
domain_info.age_days |
Days since the domain was registered, when the registry publishes it. |
mailbox |
Only when verify_mailbox was true. result is deliverable, undeliverable, catch_all (the server accepts any address) or unknown. |
risk |
Score, level, verdict and reasons. See risk scores and reasons. |
Typical handling
risk = result["risk"]
if result.get("did_you_mean"):
ask_user(f"Did you mean {result['did_you_mean']}?")
elif risk["verdict"] == "refuse":
reject("Please use a permanent email address you can receive mail at.")
elif risk["verdict"] == "review":
require_email_confirmation()
else:
accept()
Frequently asked questions
Does the email check send an email?
No. We look at the address and its domain's DNS records. Even with verify_mailbox, we only start an SMTP conversation and stop before any message is sent.
Why is mailbox verification optional?
It's slower (up to a few seconds), some mail providers always answer "yes" (catch-all), and large providers like Gmail don't reveal whether a mailbox exists. For signup forms, the default check plus email confirmation is usually the best mix. Mailbox verification shines for cleaning lists of business addresses.