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

How-to guide

How to Find Someone's Email Address from LinkedIn (API Method)

Send the profile URL to one endpoint, get back an address with a status, and send only to the statuses worth trusting.

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

You find someone's email from LinkedIn by sending the profile URL to an enrichment endpoint that returns the address it holds for that person. The URL is an identifier, not an address, so you need a data source behind it.

This guide uses the LeadOcean API. One call takes a linkedin_url and returns a work email with a deliverability status. Every step has a request you can run.

TL;DR

  • It takes about 10 minutes from key to first address.
  • One lookup spends 1 record. The full walkthrough spends 3 to 5. Counts and misses are free.
  • Send only to verified, catch_all_valid or catch_all. Everything else gets skipped or checked first.

Prerequisites

  • A LeadOcean API key from app.leadocean.io. The free plan has 1,000 records, one-off, and no card.
  • The key in your shell as $LEADOCEAN_API_KEY.
  • curl and jq.
  • A LinkedIn profile URL. The examples use a placeholder.
bash
export LEADOCEAN_API_KEY="paste-your-key-here"

Step 1: Look up one profile by URL

Send the URL to POST /v1/people/enrich with reveal_email set to true. Enrich takes exactly one of linkedin_url, email, phone or person_id.

bash
curl -s https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "linkedin_url": "https://www.linkedin.com/in/jane-doe-example",
    "reveal_email": true
  }' | jq '.data.contact_data | {email_status, contact_emails}'

A match costs 1 record. If we hold nothing for that person, the call is a 404 and costs nothing. reveal_email costs no extra record.

Step 2: Read the status before you send

The status says how far to trust the address. verified was tested. catch_all_valid means the mailbox was confirmed on a domain that accepts everything. catch_all means the domain accepts everything and the mailbox is unproven.

bash
curl -s https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/jane-doe-example", "reveal_email": true}' \
  | jq -r '.data.contact_data
    | select(.email_status | IN("verified","catch_all_valid","catch_all"))
    | .contact_emails[0].email'

Empty output means the status failed the filter. LeadOcean gives no refund for bounced emails, so this check is your protection. Our catch-all explainer covers why catch_all is sendable only at low volume.

Step 3: Loop over a list of URLs

For a short list, loop in the shell. Keep the pace under your plan's rate limit: 5 requests a second on Free, 50 on Solo, 200 on Agency.

bash
while read -r url; do
  curl -s https://api.leadocean.io/v1/people/enrich \
    -H "x-api-key: $LEADOCEAN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"linkedin_url\": \"$url\", \"reveal_email\": true}" \
  | jq -r --arg u "$url" '[$u, (.data.contact_data.email_status // "no match"), (.data.contact_data.contact_emails[0].email // "")] | @csv'
  sleep 0.25
done < urls.txt > results.csv

urls.txt holds one profile URL per line. Rows with "no match" are 404s and cost nothing. Add the select filter from Step 2 if you want only sendable rows.

Step 4: Size the audience instead of looking up names

If you have no URLs yet, build the list from filters. Count first, because counts are free. Send count=true and limit=1 as query parameters.

bash
curl -s -G https://api.leadocean.io/v1/people/search \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "jobLevel=VP" \
  --data-urlencode "jobFunction=Sales & Business Development" \
  --data-urlencode "country=US" \
  --data-urlencode "emailStatus=verified,catch_all_valid,catch_all" \
  --data-urlencode "count=true" \
  --data-urlencode "limit=1" | jq '.meta | {total, totalIsExact, countOnly}'

REST meta.total stops at 100,000, so a large audience comes back as a floor. When you run the real search, each person returned costs 1 record and carries a person_id you can pass to enrich.

Step 5: Export a large list as a CSV

Past a few hundred rows, export instead of looping. Bulk CSV export is included on Solo and Agency, not on Free. The Exports page in the app has a filter builder, a column picker and a price preview before you start.

bash
curl -s https://api.leadocean.io/v1/exports \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "us-vp-sales",
    "filters": {
      "jobLevel": ["VP"],
      "jobFunction": ["Sales & Business Development"],
      "country": ["US"],
      "emailStatus": ["verified", "catch_all_valid", "catch_all"]
    },
    "limit": 5000,
    "reveal": "email"
  }'

The search filters go inside filters, and limit sets the row count. One request exports up to 50,000 rows, and 500,000 rows a day. Each row costs 1 record. Poll GET /v1/exports/{id} until the file is ready.

What you get

Step 4 is free. We ran it on 2026-10-21 with leadocean_count_leads: US VPs in Sales & Business Development with a verified, catch_all_valid or catch_all address counted 129,494, exact, across about 58,000 employers. That is a count of people with an address in those three statuses, not every VP we hold.

Across the whole database, people with a work email in those same three statuses counted 106,756,002 on 2026-10-21, also exact.

A single lookup comes back in the shape below. This is the response shape from the API reference, with placeholder values.

json
{
  "success": true,
  "data": {
    "profile_data": { "...": "name, title, company" },
    "contact_data": {
      "has_email": true,
      "email_status": "verified",
      "email_type": "work",
      "contact_emails": [
        { "email": "jane.doe@acme.com", "type": "work", "status": "verified" }
      ]
    }
  }
}

Since 2026-10-17 the same call also returns resume_data when we hold it: past roles, education, certifications and awards. Past employers carry no company_id yet.

Troubleshooting

ErrorCauseFix
401The x-api-key header is missing, or the key is wrong or revoked.Copy a fresh key from the app and reload $LEADOCEAN_API_KEY.
402Your records are spent. On Free the 1,000 are a one-off allowance.Check GET /v1/account, or move to Solo ($97 a month) or Agency ($497 a month).
429Over your plan's rate on one key (5 a second on Free, 200 on Agency).Wait the Retry-After seconds, then retry slower.
404 on enrichWe hold nothing for that profile URL.Nothing was charged. Skip the row or search by company domain and title instead.
Empty search resultsA filter value is not an exact enum string, such as Vice President for VP.Call leadocean_list_enum_values and pass the exact string.
Export refusedOne export is capped at 50,000 rows a request and 500,000 a day.Split the job across requests and days, or narrow the filters.

FAQ

Does LinkedIn show email addresses?

Not reliably, and you should not scrape it to find out. A profile URL identifies a person. The address has to come from a data source that holds it, which is what the enrich call does.

How much does one LinkedIn lookup cost?

1 record on a match, nothing on a 404. The free plan has 1,000 records, one-off, so you can look up up to 1,000 matched profiles before paying.

Can I look up a person by name and company instead?

Not in one call. There is no name plus domain lookup. Search by company domain and title first, then enrich by person_id. Our VP of Sales guide shows that flow.

Can I get a phone number from the same profile?

Yes. GET /v2/people/phone returns phone numbers, and it costs 1 record per call, including a call that finds nothing.

Is it legal to email someone found this way?

Rules differ by country, and this guide is not legal advice. Check the law where your recipient sits and keep the message relevant to their role.

The same recipe works by title: see VP of Sales, VP of Marketing and VP of Engineering. More recipes live in the blog hub. Plans are on pricing.

Turn LinkedIn URLs into verified emails, free

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

Get your free API key →