A reverse Gmail search takes an address such as jane.doe@gmail.com and returns the person who holds it. This guide runs it three ways: by hand, by API, and by AI agent. Placeholders (Jane Doe, acme.com) stand in for real people.
TL;DR
- Manual checks cost nothing but resolve few addresses. Use them for one-off lookups.
- One API call to
POST /v1/people/enrichwithemailreturns the person. A match costs 1 record. A miss is a 404 and costs 0. - Takes about 10 minutes. Spends 1 record per match, so the Free plan's 1,000 records cover about 1,000 matched addresses.
Prerequisites
- A LeadOcean API key in
$LEADOCEAN_API_KEY. Free gives one key and 1,000 records for life, no card. Get it at app.leadocean.io. curlandjq.- A Gmail address you have a lawful reason to look up. A Gmail address is a personal address. LeadOcean's docs publish no match rate by address type, so test a small sample before a big run.
- Optional: Claude, or another MCP client, for step 5.
Step 1: Try the free manual checks first
Manual checks resolve a minority of addresses, but they cost nothing and need no key. Run them before you spend a record.
"jane.doe@gmail.com"
"jane.doe" "Acme"
"janedoe" site:linkedin.com/inThe first query searches the exact address. The second pairs the local part with a likely employer. The third tries the local part as a username. Expect hits only when the person published the address or reuses the handle.
Manual checks have two limits. They return pages, not a structured record. And they cannot tell you whether the address still delivers. Steps 2 and 3 cover both.
Step 2: Look up the person by API
Send the address to the enrich endpoint. It takes exactly one of linkedin_url, email, phone or person_id.
curl -s -X POST "https://api.leadocean.io/v1/people/enrich" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "jane.doe@gmail.com"}' | jq .A match costs 1 record. If nobody holds the address, you get a 404 and spend nothing. That makes enrich the cheaper reverse lookup for Gmail addresses, where misses are common.
GET /v2/people/reverse?email=... also works. It returns a thinner identity block (name, title, employer) and a status for the address you sent. But v2 contact endpoints cost one record per call, including a call that finds nothing. For a list with many misses, use enrich.
Step 3: Read the address status before you send
A match is evidence, not proof, and not a guarantee of delivery. Read email_status and email_type on the result.
curl -s -G "https://api.leadocean.io/v2/people/reverse" \
--data-urlencode "email=jane.doe@gmail.com" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
| jq '{who: .data.full_name, matched_in_record: .data.matched_in_record, status: .data.matched.status, type: .data.matched.type}'This call spends 1 record, hit or miss, so run it only on addresses that enrich already matched. matched_in_record: false means the person was matched upstream, but their record does not list the exact address you sent. It does not mean nobody was found. Nobody found is a 404.
The status values are verified, catch_all_valid, catch_all, risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, derived and none. Send to verified. Treat risky and unknown as a test batch. LeadOcean gives no refund for bounces, so read the status first.
Step 4: Size a bigger run for free
If you are checking many people at once, size the list before you spend. A people search with count=true as a query parameter and limit=1 is free. The data comes back empty and meta.total holds the count, capped at 100,000.
curl -s -X POST "https://api.leadocean.io/v1/people/search?count=true&limit=1" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"country": ["United States"], "jobLevel": ["VP"]}' | jq '.meta'Put count=true in the query string, not the JSON body. The body rejects unknown fields. There is no batch reverse lookup in the docs, so a list of addresses means one call per address. Throttle to your plan: 5 requests a second on Free, 50 on Solo, 200 on Agency.
while read -r addr; do
curl -s -X POST "https://api.leadocean.io/v1/people/enrich" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"email\": \"$addr\"}" | jq -c '{addr: "'"$addr"'", found: (.success // false)}'
sleep 0.25
done < gmail_addresses.txtThe sleep 0.25 keeps a Free key under 5 requests a second. A miss returns a 404 body, so found is false for those.
Step 5: Ask an agent instead
The hosted MCP server at https://api.leadocean.io/mcp signs in with OAuth. No key is pasted. The tool for this lookup is leadocean_get_lead, which takes an email and returns the full person record for 1 record.
Who holds jane.doe@gmail.com? Give me their title and employer,
and tell me the email status before I send anything.A get_lead call that finds nobody costs nothing, the same as the REST 404. Setup is in Reverse Email Lookup over MCP.
What you get
This is the response shape from the API reference for GET /v2/people/reverse, with placeholder values. It is not a real person.
{
"success": true,
"data": {
"person_id": "1234567",
"person_group_id": "1234567",
"linkedin_url": "https://www.linkedin.com/in/jane-doe",
"full_name": "Jane Doe",
"job_title": "Finance Manager",
"company_name": "Acme",
"company_domain": "acme.com",
"query": { "email": "jane.doe@gmail.com" },
"matched": { "email": "jane.doe@gmail.com", "status": "verified",
"verified_batch_date": null, "type": "personal" },
"matched_in_record": true
},
"meta": { "source": "leadocean", "schema": "leadocean.contact.reverse.v2",
"stability": "stable", "credits": 1 }
}Every identity field can be null. verified_batch_date is always null on a personal address: the reference says LeadOcean's own verifier has not tested personal addresses, so their status comes from a supplier. About one person in five has no LinkedIn URL, so a real match can arrive without one. The enrich call returns the fuller record: profile data, contact data and, since October 2026, career history in resume_data.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong key | Send x-api-key: $LEADOCEAN_API_KEY. Check the key in the app. |
| 403 | Key lacks the enrich scope | Create a key with the enrich scope. Free keys get search and enrich. |
| 404 | Nobody holds this address | Free. Try a manual check, or enrich by linkedin_url instead. |
| 429 | Above your plan's rate limit | Back off for the Retry-After header. Limits are 5 a second on Free, 200 on Agency. |
| 402 | Records spent | Free is 1,000 for life. Move to Solo ($97 a month) or Agency ($497 a month). |
| 400 | Both email and phone sent, or neither | Send exactly one identifier. |
FAQ
Can you find who owns a Gmail address for free?
Yes, within limits. Manual searches are free. A LeadOcean 404 is free. A match costs 1 record, and the Free plan gives 1,000 records once, with no card.
Does reverse Gmail search work on every address?
No. LeadOcean holds 693M people and 366M with an email (measured 2026-09-23). An address outside that set returns a 404. The docs publish no match rate for personal addresses, so sample first.
Is the result proof the person owns the address?
No. It is evidence. Check matched_in_record and matched.status, and treat a lookup as a lead to confirm, not a fact.
Can I search by name instead of address?
Not directly. There is no name plus domain lookup. Search by company domain, then enrich by person_id.
Where do I compare other tools?
See the best reverse email lookup tools, the reverse email lookup page and the Enrichments hub. Plans are on pricing.
Run your first reverse Gmail search free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →