Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

How-to guide

How to Search on LinkedIn by Email (API and Bulk Loop)

One email in, the LinkedIn profile URL out. One GET request, 1 record per call. For lists with many misses, enrich by email, where a miss is free.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

Send the email to GET /v2/people/reverse and read linkedin_url from the response. You skip the manual search. Each call costs 1 record, including a call that finds nobody.

This guide covers one address, the cases where the URL comes back empty, and a bash loop for a list.

TL;DR

  • One call to GET /v2/people/reverse with email= returns the person, title, company and LinkedIn URL.
  • Setup takes about 10 minutes. The loop runs at up to 5 requests a second on Free and 200 on Agency.
  • Each reverse call spends 1 record, hit or miss. Enrich by email charges only for matches. Free gives you 1,000 records once, no card.

Prerequisites

  • A LeadOcean API key with the enrich scope, exported as $LEADOCEAN_API_KEY. Start free: Free keys get both scopes.
  • curl and jq.
  • A list of emails to look up, one per line, in emails.txt.

Step 1: Look up one email

Pass the address as a query parameter. Use -G with --data-urlencode so a + in the address survives.

bash
curl -s -G "https://api.leadocean.io/v2/people/reverse" \
  --data-urlencode "email=jane.doe@acme.com" \
  -H "x-api-key: $LEADOCEAN_API_KEY"

The same endpoint also takes phone= instead of email=. Send one, never both. There is a POST version with a JSON body ({"email": "jane.doe@acme.com"}) if you prefer it.

If you expect many misses, send the address to POST /v1/people/enrich with email instead. A person we hold nothing for is a 404 there and costs nothing. The full record carries the profile link at profile_data.profile_url (enrich docs).

Step 2: Read the profile URL

Pipe the response through jq to keep only what you need.

bash
curl -s -G "https://api.leadocean.io/v2/people/reverse" \
  --data-urlencode "email=jane.doe@acme.com" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  | jq '.data | {linkedin_url, full_name, job_title, company_name, person_id}'

Two fields matter most. linkedin_url is the profile. person_id is the handle you keep if the URL is empty.

Step 3: Handle a missing LinkedIn URL

About one person in five has no LinkedIn URL on record, so linkedin_url can be null on a real match. Keep the person_id and enrich it for the full record.

bash
curl -s -X POST "https://api.leadocean.io/v1/people/enrich" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"person_id": "1234567"}'

Enrich takes exactly one of linkedin_url, email, phone or person_id. It costs 1 more record, so call it only for the rows that need it. Since October 2026 it also returns career history: past roles, education and certifications.

Step 4: Run a list

The docs describe no batch version of the reverse endpoint, so a list is one call per address. This loop writes a CSV of email,linkedin_url, skips misses and backs off on a 429. Every call spends 1 record, including the misses.

bash
#!/usr/bin/env bash
echo "email,linkedin_url,full_name,job_title"
while read -r email; do
  while :; do
    code=$(curl -s -o /tmp/lo.json -w "%{http_code}" -G \
      "https://api.leadocean.io/v2/people/reverse" \
      --data-urlencode "email=$email" \
      -H "x-api-key: $LEADOCEAN_API_KEY")
    [ "$code" = "429" ] && { sleep 1; continue; }
    break
  done
  if [ "$code" = "200" ]; then
    jq -r --arg e "$email" \
      '.data | [$e, (.linkedin_url // ""), (.full_name // ""), (.job_title // "")] | @csv' /tmp/lo.json
  fi
  sleep 0.25
done < "$1"

Save it as lookup.sh and run ./lookup.sh emails.txt > profiles.csv. The sleep 0.25 keeps you under the Free limit of 5 requests a second. On Agency (200 a second) shorten it. Keep one key per script, because the limit is per key.

Step 5: Run it from an AI agent

The MCP server has no tool named for reverse lookup. Use leadocean_get_lead and pass the email. It returns the full person record and counts as 1 record.

text
Find the LinkedIn profile for jane.doe@acme.com.
Return the profile URL, the job title and the company.

Connect the server at https://api.leadocean.io/mcp. Sign-in is OAuth, so no key is pasted. The email to LinkedIn page has the setup.

What you get

This is the response shape from the API reference, with placeholder values. It is not a live record.

json
{
  "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@acme.com" },
    "matched": { "email": "jane.doe@acme.com", "status": "verified",
                 "verified_batch_date": "2026-09-14", "type": "work" },
    "matched_in_record": true
  },
  "meta": { "source": "leadocean", "schema": "leadocean.contact.reverse.v2",
            "stability": "stable", "credits": 1 }
}

Check matched_in_record. When it is false, the person was matched on your email upstream but the record does not list that exact address. Verify the profile before you act on it.

If nobody holds the address, the API answers 404. A v2 contact call still costs 1 record when it finds nothing.

Check the match before you use it

A match is evidence, not proof. Three checks take seconds and catch most bad rows.

  • matched_in_record. true means the record lists the exact address you sent. false means the match came through another route, so look at the profile yourself.
  • matched.status. It carries the deliverability status of the address you sent, such as verified or catch_all. A profile found from an invalid address is weaker evidence.
  • company_domain. Compare it with the domain in the email. A work address at acme.com should return a person at acme.com. If it does not, the person may have changed jobs, so check job_title and the profile.

Records can duplicate. The same person may appear under different person_id values. Compare person_group_id to deduplicate your output.

Pick the cheapest path for your volume

Reverse lookup spends 1 record per call, hit or miss. Enrich by email spends 1 record per match only. Either way a sample run is cheap.

  • Under 1,000 emails, one time. The Free plan covers it. No card, no monthly fee.
  • A list you refresh every week. Solo is $97 a month for one person, with phones and bulk CSV export included.
  • A team or an agency. Agency is $497 a month with 5 keys and 200 requests a second. Paid plans run on a fair-use pace, not credits.

Run 100 addresses first and count the 404s. That is your real match rate on your own list. The docs publish no match rate for reverse lookups, so your sample is the only honest number. Plans and limits are on the pricing page.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerCheck that $LEADOCEAN_API_KEY is set in the shell that runs the script.
403The key lacks the enrich scopeCreate a key with the enrich scope in app.leadocean.io.
404No person holds that email or phoneExpected for some addresses. Skip the row. For free misses, enrich by email instead.
429Above the plan's rate limit: 5 a second on Free, 200 on AgencyWait for the Retry-After header, then retry. The loop above sleeps 1 second.
402The key has spent its recordsFree allows 1,000 once. Move to Solo or Agency. A 402 is never billed.
200 with linkedin_url nullThe person has no LinkedIn URL on recordEnrich by person_id (Step 3).

FAQ

Can I search LinkedIn itself by email?

You query a dataset that holds the email next to the profile, not LinkedIn. LeadOcean holds 693M people, 366M with an email (measured 2026-09-23).

Does a personal email work?

The endpoint takes any email address, and matched.type labels the one you sent. The docs publish no match rate per address type. Test a sample of your own list first.

How many records does a list cost?

One per email on the reverse endpoint, hit or miss. On enrich by email only matches cost, so 10,000 emails cost 10,000 records or fewer. Free covers the first 1,000 once. Agency is $497 a month with no per-record price, inside fair use.

Can I go from a LinkedIn URL to an email instead?

Yes. See LinkedIn to email and the guide to finding an email from a LinkedIn profile. More guides are on the blog.

Look up your first LinkedIn profile by email, free

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →