The public-provider lookup
curl -sS https://api.emvero.tech/v1/public-provider \ -H "Authorization: Bearer emv_your_credential" \ -H "Content-Type: application/json" \ -d '{"domain":"gmail.com"}'{ "domain": "gmail.com", "ascii_domain": "gmail.com", "public_provider": true, "dataset_version": "2026-08-18.1+ab12cd34ef56"}It costs nothing. No credits are spent, no X-Credits-Charged or
X-Credits-Remaining is returned, and an empty balance does not refuse it.
It is the cheapest of the three free lookups: an answer from a list held in memory, with no resolver query, no SMTP session and no destination’s patience spent. The catch-all lookup costs one DNS query on a cache miss; this costs not even that.
It still needs a credential, like every other operation. What is free is the answer, not the access.
The question it answers
Section titled “The question it answers”Not whether the address is free, and not whether the domain receives mail. Whether the domain tells you who the person is.
someone@gmail.com could be anybody. someone@siemens.com works at Siemens.
Every domain in the list is one a provider hands out to the general public, so
the answer for it is: this one tells you nothing.
It answers in one direction only
Section titled “It answers in one direction only”This is the whole design and reading it the other way is the mistake worth guarding against.
true establishes something. The domain belongs to a provider that hands
mailboxes to anybody who asks - Gmail, Outlook, Posteo, an ISP’s consumer mail.
You can act on it.
false establishes nothing. The domain may be an organisation’s own, or it
may be one of the long tail of small providers no list reaches. Reading false
as this is a work address is the misreading, and there is deliberately no
corporate flag in the response for you to read instead - a list of every public
provider on earth does not exist, so the field claiming to be its complement
would be wrong about exactly the domains you would most want it right about.
The asymmetry is on purpose rather than a gap being closed later. A wrong true
tells you an employee’s work address is a personal one, which is a wrong answer
with money behind it; a missing entry costs you only the signal. So the list
covers the providers people actually use and does not chase the tail.
It is not a quality judgement
Section titled “It is not a quality judgement”A Gmail address is a perfectly good address. Nothing here is a defect, and this signal never moves a verdict - the same is true of every risk annotation this service produces.
What it is for is products that treat a personal mailbox differently from a company one: a B2B trial that wants a work address, a sales lead you are about to route, an invoice address. Whether that difference matters is a business decision the field informs rather than makes.
What it does not tell you
Section titled “What it does not tell you”It answers exactly one question, and it is the same signal a verification
reports in checks.public_provider, read from the same
bundle, so the two cannot disagree.
Everything else a verification establishes is absent:
- It does not say the domain resolves, publishes mail routing, or accepts mail
at all. A domain registered ten minutes ago and pointed nowhere comes back
"public_provider": falseon the strength of the list alone. - It does not say a mailbox exists. Nothing is asked of any destination.
- It cannot produce a verdict. There is no
status, noactionand noreason_codeshere, because none of them would be earned. - It is not the same question as who runs this domain’s mail server. Google
runs Gmail and also runs a great deal of corporate mail;
google.comitself is not in this list, because that is where Google’s own staff read mail.
Where the answer comes from, and dataset_version
Section titled “Where the answer comes from, and dataset_version”The list is a reviewed file rather than an assembled one, which is the difference from the disposable lookup. Throwaway providers appear overnight and that list is rebuilt from four feeds daily. Public mailbox providers do not: the head of this list moves on the timescale of years, so it is curated and changes when somebody changes it.
dataset_version identifies the bundle both lists travel in. It is a label plus
a digest of the values, so re-indenting a file does not mint a new version
and a changed entry cannot fail to. Two things it is for: pinning a support
conversation about a domain to the exact list that answered, and knowing that a
cached answer of yours was taken against a bundle that has since moved.
Sending an address instead of a domain
Section titled “Sending an address instead of a domain”domain accepts a whole address, because the code asking this question usually
has one:
{ "domain": "someone@gmail.com" }Only the domain is read. The local part is discarded before anything else happens - before the domain is even normalised - and appears in no response, no log and no error message. It is a convenience rather than a second field, and sending one has exactly the same effect as sending the domain by itself.
The domain is normalised the way every other lookup on this service normalises one, so an internationalised name is converted before it is compared and comes back in both forms.
When to use this, and when to buy a check
Section titled “When to use this, and when to buy a check”Use this to sort personal addresses from company ones - qualifying a signup, routing a lead, deciding whether to ask for a work address - and to do it on volumes where paying per domain would not be worth it.
Buy a domain-depth check when the question is whether
mail can reach the domain at all. It resolves the name, reads the mail routing,
returns a real verdict, and reports every risk signal at once rather than this
one. It costs 2 credits and answers something this cannot.
Buy a full check on a signup form. Neither of the above
asks the destination about the recipient.
Errors
Section titled “Errors”| Status | Meaning |
|---|---|
400 |
missing_domain, or invalid_domain for something no lookup can be made for. Fix the request; it will not succeed on retry. |
401 |
Missing or unrecognised credential. |
413 |
The request body is larger than permitted. |
429 |
Caller or source budget exceeded. Back off; honour Retry-After. |
503 |
annotation_unavailable - the reference lists are not loaded, so no answer can be given. |
The 503 matters more here than on the lookups beside it, and for a reason
worth stating. On those, a negative is a real answer and a service that had lost
its lists answering false would at least be visibly odd. Here false is
exactly what an unlisted domain legitimately gets - so a service answering it to
everything would be indistinguishable from a working one until somebody asked
about gmail.com. It refuses instead. Treat it as no answer, not as a negative
one.