Work out the most likely work email for someone, and say how sure it is.
Company mail follows a house pattern, so this builds the addresses that pattern could produce for the name given (`first.last@`, `flast@`, `first@`, and so on) and asks the domain's mail server which of them it will accept. The conversation stops one command short of sending: no message is delivered, and the person is not contacted.
**The employer comes from you, and `employment` says whether anything supports it.** This endpoint builds an address at the domain you name; it cannot know on its own that the person works there. So `confidence_score` answers "is this the right shape for an address at this domain", and `employment.status` answers "is this person even at this domain":
* `confirmed` - an address is on file for them there. * `contradicted` - they are on file at a different employer. The score is capped hard, because a well-shaped address for the wrong company looks exactly like a good answer otherwise. * `unknown` - nothing on file either way. The score is capped below the high band: the address is what somebody at that domain would have, and it assumes they are there.
**Read `status` before using the address.**
* `valid` - the mail server accepted this address and rejected one that cannot exist, so it is discriminating between real and fake recipients. This is the only status that means the mailbox was confirmed. * `catch_all` - the domain accepted an address made of random hex, so it accepts everything. The address returned is the most common pattern and is unconfirmed. * `unverifiable` - the question could not be asked, or the answer means nothing. Outbound port 25 blocked, greylisting, or a provider such as Microsoft 365 that answers 250 for every recipient. `reason` says which. * `invalid` - every candidate was rejected, or the domain has no MX record at all and cannot receive mail.
`confidence` compresses that to `high`, `low`, `guess` or `none` for callers who want one field rather than four.
Anything found there comes back under `stored`, and becomes the primary answer only when the probe could not produce a verified one.
Query parameters
| Name | | Meaning |
|---|
| first_name | required | The person's given name, such as Jane. Accents are folded to ASCII and honorifics (Dr., Prof.) are stripped, so pass it as written on their profile. |
| last_name | required | The person's family name, such as Doe. Hyphenated names are kept whole (muller-schmidt), and post-nominals (PhD, Jr.) are stripped. |
| domain | required | The employer's mail domain, such as example.com. This is the domain their email is on, which is often not the domain their website is on - check the MX record if unsure. Do not pass a LinkedIn slug or a full URL. |
| verify | optional | true asks the receiving mail server whether each candidate exists, which is what separates a verified address from a guess. false skips the network entirely and returns the most common pattern, which is fast and free but unconfirmed. |
Request
curl 'https://api.rynora.dev/api/v2/contact/email?first_name=Jane&last_name=Doe&domain=example.com' \
-H 'X-API-Key: $RYNORA_KEY'Response
The fields below appear inside data. Types are shown in place of values; string|null means the field is always present and may be null.
{
"candidates": [
{
"accepted": "string|null",
"code": "string|null",
"email": "string",
"pattern": "string"
}
],
"confidence": "string",
"confidence_factors": [
"string"
],
"confidence_score": "integer",
"domain": "string",
"email": "string",
"employment": {
"employers_on_file": [
"<empty>"
],
"note": "string",
"status": "string"
},
"first_name": "string",
"full_name": "string",
"house_pattern": {
"agreement": "number",
"confirmed": "boolean",
"pattern": "string",
"sample": "integer"
},
"last_name": "string",
"mx": [
"string"
],
"pattern": "string",
"probing_enabled": "boolean",
"reason": "string",
"source": "string",
"status": "string",
"stored": [
"<empty>"
]
}