Reverse Email Lookup API: Find the Person Behind an Email
Run a reverse email lookup through an API: one address in, the person and their company out, with the fields we got back and the traps to avoid.

Find out who is behind an email address, and where they work, in one prompt. Paste this into your agent:
Set up https://monid.ai/SKILL.md, and then use Monid to run a reverse email lookup on patrick@stripe.com and give me the person's job title, location and company, plus the fuzzy flag and the date the record was last indexed.
One prompt turns an address into a profile. 1 min setup · 2-6 hrs saved.
You have an email address, or a few thousand, and you want to know who owns each one: the name, the job title, the company, maybe a LinkedIn profile. That is a reverse email lookup, and most of the tools that do it are built for a person typing one address into a box. This guide covers the API route, what one live call returned on 2026-10-16, and the traps in the output. It runs through Monid, the OpenRouter for agent tools: one key, one balance, every tool priced per call.
What is the easiest way to run a reverse email lookup through an API?
Monid. Install it once, add a key, and your agent calls a lookup endpoint with an email address and gets the person back as typed JSON, with no contract and no vendor account to set up.
- Pay per call. One lookup is billed at $0.0049 (Verified 2026-10-16 on the people enrichment tools page). An address the provider does not know answers 404 and costs nothing. Buy calls as you need them: no monthly plan and no minimum top-up. Discovery and inspection are free; only a successful run bills.
- One install, every API. The same key and balance call the lookup, an email verifier, a name-to-email finder and every other tool on Monid. Verify an address, then look it up, without opening a second account.
- Lives inside your agent. Install the CLI, add your key, run the prompt above, and the tool is there whenever your agent needs it, with nothing to keep running. Your agent reads
SKILL.mdand learns the rest, so setup is about a minute.
At that price, looking up 100 addresses costs at most $0.49 (Verified 2026-10-16), and fewer if some are misses.
How do you run a reverse email lookup on a list of addresses?
Run one lookup per address and loop it over the list. The endpoint is /combined/find from the provider hunterio. It takes one parameter, email, and returns the person and their company in one response.
| Route | What you get | Cost shape | Fits |
|---|---|---|---|
| Free lookup website | One address at a time, typed by hand | Free, often limited | Checking a single address |
| Database platform seat | Contact records in a web app and an export | Plans, often by the seat | A sales team working in one tool |
| Build your own from public pages | Whatever your searches find | Your hours | A one-off research task |
| Monid lookup endpoint | Typed JSON per address, person plus company | Pay per call, buy flexibly | Lists, signup flows, agents |
Monid fits a list because the work is the same call repeated, and you pay for the addresses it resolves and nothing between runs.
For agents
Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:
set up https://monid.ai/SKILL.md
It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.
For humans
npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main
Inspect, then look up one address
monid inspect -p hunterio -e /combined/find
monid run -p hunterio -e /combined/find --query '{"email": "patrick@stripe.com"}'
Loop it over your list
Put one address per line in emails.txt and write one file per address:
mkdir -p out
while read -r e; do
monid run -p hunterio -e /combined/find --query "{\"email\": \"$e\"}" > "out/$e.json"
done < emails.txt
Each hit bills one call and each 404 bills nothing.
Or hand the whole job to an agent
Give this to your agent![]()
Set up https://monid.ai/SKILL.md, and then use Monid to take this list of email addresses, run a reverse lookup on each, and give me one table with the address, job title, company, location and the fuzzy flag, leaving a row blank when the lookup finds nothing.Is there a free reverse email lookup, or can you build one yourself?
There are free lookup sites, and they suit one address at a time. You paste the address into a box and read the result. They are made for a person at a keyboard, so a list, a signup flow or an agent needs something with an API and a stable response shape.
Building one yourself is possible for a single case. You search the address in a search engine, check whether it appears on a public profile or a company page, and look for a matching name on LinkedIn. It works when you have ten addresses and an afternoon. It does not turn into a pipeline: results change with the search engine, nothing gives you a confidence field, and every address costs minutes of reading.
The Monid route is the choice for anything you will run more than once. The index is maintained for you, the output is typed JSON with a fuzzy flag and two dates instead of a page you parse, and one lookup is $0.0049 (Verified 2026-10-16). Discovery and inspection are free, so you can read the full schema before you spend anything.
What does a reverse email lookup return, and what can you build with it?
A reverse email lookup returns a person record keyed on the mailbox, and /combined/find adds the company record on top. We ran it on 2026-10-16 against patrick@stripe.com, so the fields below are what came back. The mailbox belongs to an IT administrator in Madison, Wisconsin, not to the better-known person with the same first name at the same company, and that is the endpoint working: a company mailbox belongs to whoever was given it.
The person record
{
"name": { "fullName": "...", "givenName": "...", "familyName": "..." },
"email": "patrick@stripe.com",
"location": "Madison, Wisconsin, United States",
"timeZone": "America/Chicago",
"geo": { "city": "Madison", "stateCode": "WI", "countryCode": "US", "lat": 43.07305, "lng": -89.40123 },
"employment": { "domain": "stripe.com", "name": "Stripe", "title": "IT Administrator",
"role": "it", "subRole": null, "seniority": null },
"linkedin": { "handle": "..." },
"phone": "...",
"fuzzy": false,
"emailProvider": "google.com",
"indexedAt": "2026-10-15",
"activeAt": "2026-10-17",
"inactiveAt": null,
"bio": null, "site": null, "avatar": null,
"github": { "handle": null }, "twitter": { "handle": null }, "facebook": { "handle": null }
}
Name, location, title, LinkedIn handle and phone came back populated (shown masked above). Bio, site, avatar, GitHub, Twitter and Facebook came back null. A profile is whatever the provider has observed, not a fixed shape, so design the table for nulls in the social columns.
The company record
The same call returned a company block: legal name, domain, industry codes, a description, founding year, headquarters, metrics.employees as a band (10K-50K) next to an exact employeesCount, funding rounds and a technology list of about 100 entries. /people/find on the same address returned the identical person record, with the same id, and no company block.
What you can build with it
- An inbound lead qualifier. When a form submits a work email, resolve it before a human sees it and route on
employment.title,roleandseniority. - A CRM clean-up. Fill blank title and company columns for contacts you only have an address for, and store
indexedAtbeside each value so you can see how old it is. - A sender check on unknown mail. Look up the address of an unfamiliar sender and compare the company on the record with the domain in the address.
- A contact finder in reverse. Go the other direction when you have a person and want the address, with a name-to-email endpoint from the same provider, as in finding an email by name and company.
What goes wrong when you look up emails in bulk?
Four things show up once you read the output of more than one address. All four are from the 2026-10-16 runs or the live schema.
Why does a surprising result not mean a wrong one?
Because the mailbox belongs to a specific employee. People often type an address expecting a well-known person and get a colleague who shares the first name. The record is correct. The field that tells you whether to trust it is fuzzy, which was false on our call, meaning a direct match rather than an inference from a name pattern. Keep it:
person = resp["data"]["person"]
confidence = "observed" if person["fuzzy"] is False else "inferred"
row.update(title=person["employment"]["title"], confidence=confidence,
indexed_at=person["indexedAt"], active_at=person["activeAt"])
If you drop fuzzy on the way into your database, every inferred row looks like an observed one.
Why is a 404 not an error?
Because it is the provider saying it has no record. We ran /people/find on an address made up for the test, and the run completed with providerResponse.httpStatus 404, output null, and a bill of zero. Treat it as an empty row, not a failure to retry. Retrying a 404 spends time and finds nothing.
Why is emailProvider not a personal-address flag?
Because it names the mail host, not the kind of address. Our record carried emailProvider: "google.com" for a company mailbox on a company domain, since the company runs its mail on Google. To split personal from corporate addresses, check the domain you can see in the address.
How old is the record, and what does a list cost?
The two dates say it. indexedAt was 2026-10-15 and activeAt 2026-10-17 on our call, and the company block carried its own indexedAt of 2026-06-18, so one response mixes ages. A person who changed jobs last month can still resolve to the old employer until the provider sees them again. Store the dates and age your rows by them. Each hit bills $0.0049 (Verified 2026-10-16). The two hits we ran billed $0.0098 in total (Verified 2026-10-16), the miss billed $0, and the median run time is about 1.3 seconds per monid inspect.
📖 See also Enriching a list from email addresses
Which endpoint should I use for which job?
| Endpoint | What it does | Input | Billing | Price (Verified 2026-10-16) |
|---|---|---|---|---|
hunterio/combined/find | Person and company from one email | email | Per call, a 404 is free | $0.0049 |
hunterio/people/find | Person only, from an email or a LinkedIn handle | email or linkedin_handle | Per call, a 404 is free | $0.0049 |
pdl/v5/person/enrich | Second source; accepts email, phone, name plus company, LinkedIn URL or ID | POST body | Per call | $0.28 |
hunterio/email-verifier | Is this address deliverable | email | Per result, unknown free | $0.01225 |
hunterio/email-finder | The reverse direction: name and company to address | domain or company, plus a name | Per result, no-find free | $0.0245 |
Prices Verified 2026-10-16 with monid inspect; current figures at monid.ai/tools. We ran the first two, and inspected the other three without running them: the pdl call is priced above our $0.03 test limit (Verified 2026-10-16), and the verifier and finder bill per result. The first row is the default, because it costs the same as the second and returns more. The second earns its place when you start from a LinkedIn handle, or when you want the smaller response.
For a second source, the pdl endpoint is a POST, so it takes a body rather than a query:
monid run -p pdl -e /v5/person/enrich -i '{"email": "patrick@stripe.com"}'
When is another route a better fit?
The address is personal. A free-mail mailbox says nothing about an employer, and resolving it means identifying a private individual rather than a business contact. Rules about that differ by country, so check the ones that apply to you before you run a batch.
You already have the person. If your spreadsheet holds a name and a company, you want enrichment on those, or the name-to-email endpoint if the address is the missing piece. The email lookup is for the case where the mailbox is all you have.
You need the address to be deliverable. A lookup tells you who owns a mailbox. It does not tell you whether mail to it will arrive. For bounce protection run a verifier, which is a different call with a different result.
You need a free check on one address. A free lookup site does that with no key and no balance.
And the disclosure: this is Monid's blog and we resell these endpoints. The most useful advice in this post costs you nothing: keep the fuzzy flag and the two dates, treat a 404 as an empty row, and read a surprising result before you call it wrong.
Conclusion
The quickest way to run a reverse email lookup through an API is one call per address through Monid: $0.0049 a hit (Verified 2026-10-16), nothing for a miss, one key for this and every other tool, about a minute to set up and ready inside your agent whenever you need it. Searching by hand works for a handful of addresses and gets slower with every one.
Two things matter more than the endpoint you pick. A surprising result is not a wrong one, so keep fuzzy and the dates beside every row and decide how much to trust it from those. And a lookup is not a deliverability check: if bounces are the problem, verify the address first and look up the survivors.
How we estimated the time saved: wiring up a lookup vendor yourself, with an account, reading the docs, mapping the response and handling misses and nulls, is roughly 2 to 6 hours for a first working pipeline. The 1 minute is the install, key and first call once you already have a Monid key.
Free next step: run monid inspect -p hunterio -e /combined/find, then make one call on an address whose owner you already know and compare employment.title and fuzzy with what you expect. Start at monid.ai.
FAQ
Is there a free reverse email lookup?
Yes, for one address at a time: free lookup sites let you paste an address and read a result, usually with limits. For a list or an agent, an API is the better fit, and on Monid a lookup is $0.0049 per hit (Verified 2026-10-16), with no monthly plan, no minimum top-up and nothing billed for a miss. Inspecting an endpoint to read its schema and price is free.
Does reverse email lookup work on Gmail addresses?
It can return a record when the provider has seen the mailbox, but a personal address carries no company signal, so you get far less than from a work address. Split free-mail addresses out of a B2B batch and treat any result as lower value.
Can you find a phone number or social profiles from an email?
Sometimes. The person record has phone and handles for LinkedIn, Twitter, GitHub and Facebook, and on our 2026-10-16 call the phone and LinkedIn handle came back while the others were null. Treat each as optional.
What does the fuzzy flag mean?
It separates a direct match from an inference. fuzzy: false was on our record. Store it beside every row so you can tell a direct match from a guess later.
How current is the record?
As current as its dates. Our person record had indexedAt 2026-10-15 and the company block 2026-06-18, so one response can mix ages. Store both and re-check a record before acting on a title that is months old.
Published September 2026.


