Email check
POST /email-lookup: whether up to 100 email addresses can receive mail, and whether each is a throwaway, free or shared address. How the check works, the request, an example answer and every field.
POST https://service.cerberius.com/api/email-lookup
Whether each email address can receive mail, and what kind of address it is. Use it to catch typing mistakes and throwaway addresses at sign-up, or to clean a mailing list.
How the check works#
For each address, we:
- Look up the domain's mail servers (its MX records). If it has none, the check stops here: the score is
0. - At the same time, check the domain's IP address, its SPF and DMARC records, whether it's a throwaway or free email service, whether the part before the @ looks like a shared address, and whether the domain looks like a typing mistake.
- If the domain has no IP address, the check stops here.
- Find the mail server's IP address and its host name.
- Ask the mail server whether it would accept mail for the address, and for a made-up address at the same domain. No email is sent.
- Work out the
validity_score.
Some mail servers won't answer such questions, or answer slowly. Then smtp_valid is false, and comment says Unable to verify SMTP. That doesn't lower the score.
Asking mail servers takes time: a call can take several seconds, more with many addresses. All the addresses in one call are checked at the same time. Let a call run for up to 100 seconds before you give up.
Request#
Headers
X-API-Key: your key. A key made with Sign every call also needsX-TimestampandX-Signature(see Authentication and signed calls).Content-Type: application/json
Body
{ "data": ["[email protected]", "[email protected]"] }
| Field | Rules |
|---|---|
datalist of text | 1 to 100 email addresses, each up to 320 characters. Spaces around each address are removed. |
- Every item must look like an email address, such as
[email protected]. If one doesn't, the whole call fails, so check them before you send them. - The same address twice gets two results.
Example#
curl https://service.cerberius.com/api/email-lookup \
-H "X-API-Key: $CERBERIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data": ["[email protected]", "[email protected]"]}'
The answer. Values like these change over time, so yours may differ.
{
"excess_charges_apply": false,
"data": [
{
"email_address": "[email protected]",
"user": "jane",
"domain": "shop.example",
"domain_ip": "",
"mx_hosts": "",
"mx_reverse_dns": "",
"has_spf": false,
"has_dmarc": false,
"smtp_valid": false,
"smtp_catch_all": false,
"is_disposable": false,
"is_shared_address": false,
"is_free": false,
"did_you_mean": "",
"validity_score": 0,
"comment": "Lookup failed: domain has no MX records"
},
{
"email_address": "[email protected]",
"user": "jane.doe",
"domain": "gmail.com",
"domain_ip": "142.250.4.26",
"mx_hosts": "alt4.gmail-smtp-in.l.google.com.",
"mx_reverse_dns": "sm-in-f26.1e100.net.",
"has_spf": true,
"has_dmarc": true,
"smtp_valid": true,
"smtp_catch_all": false,
"is_disposable": false,
"is_shared_address": false,
"is_free": true,
"did_you_mean": "",
"validity_score": 80,
"comment": "Success"
}
]
}
Results can come back in a different order
Addresses are checked at the same time, and each result is added when it's ready. In the example, the address whose domain has no mail servers came back first. Match each result to your list by its email_address.
Every result has every field. When a check didn't run, a text field is empty ("") and a true/false field is false.
Fields#
The answer#
| Field | What it means |
|---|---|
excess_charges_applytrue/false | Always false. There are no extra charges. Kept so code written for the first version keeps working. |
datalist | One result for each address you sent. |
Each result#
| Field | What it means |
|---|---|
email_addresstext | The address you sent, without spaces around it. |
usertext | The part before the @. |
domaintext | The part after the @. |
domain_iptext | The IP address of the domain's mail server, or of the domain itself when the mail server's can't be found. Empty when the check stopped early. |
mx_hoststext | One of the domain's mail servers (from its MX records), as DNS gives it, with a dot at the end. Despite the name, it's text, not a list. Empty when the domain has no mail servers. |
mx_reverse_dnstext | The host name of the mail server's IP address (its reverse DNS), with a dot at the end. No PTR when it has none. Empty when the check stopped early. |
has_spftrue/false | The domain publishes an SPF record: which servers may send its mail. |
has_dmarctrue/false | The domain publishes a DMARC record: what to do with mail that fails those checks. |
smtp_validtrue/false | The mail server said it would accept mail for this address. false when it refused, or when it couldn't be asked (then comment says so). |
smtp_catch_alltrue/false | The mail server also accepted a made-up address at the same domain. It accepts mail for any address, so smtp_valid proves less. |
is_disposabletrue/false | The domain is on our list of throwaway email services, which give out short-lived addresses. |
is_shared_addresstrue/false | The part before the @ looks like a role or team address, such as info, sales, support or admin, rather than one person's. |
is_freetrue/false | The domain is on our list of free email providers, such as gmail.com. |
did_you_meantext | A suggested domain when this one looks like a typing mistake, such as gmail.com. It's only the domain, not the whole address. Empty when there's no suggestion, or the domain has no mail servers. |
validity_scorenumber | From 0 to 100: how likely mail to this address arrives. Higher is better. See below. |
commenttext | Success when there was nothing to note. That doesn't make the address good: read the other fields. Otherwise, notes, one per line after Comments:, such as Unable to get SPF record (the domain has none, or it couldn't be read) or Unable to verify SMTP (the mail server couldn't be asked). When the check stopped early, Lookup failed: and why, such as Lookup failed: domain has no MX records or Lookup failed: domain does not resolve to an IP. |
How the score is worked out#
validity_score adds up what the check found, from 0 to 100:
0when the domain has no mail servers.- Raise it: mail servers, an IP address for the domain, SPF, DMARC, a mail server whose host name matches the domain, a domain that isn't a throwaway service, and above all the mail server accepting the address.
- Lower it: a throwaway domain (a lot), the mail server refusing the address, a catch-all mail server, a free or shared address, a likely typing mistake, and a domain without an IP address.
Use it to sort or flag addresses, together with the fields above. For example, warn on a throwaway address or a did_you_mean suggestion, whatever the score.