TL;DR
- You do not scrape LinkedIn. You ask a people database, over MCP or REST, for profiles you can match by LinkedIn URL, title or company.
- It takes about 15 minutes. Counting is free. Each profile you enrich or search result you receive spends 1 LeadOcean record, so the walkthrough spends about 3.
- LeadOcean returns profile and career data. It does not return LinkedIn posts, comments or reactions. If you need post data, you need a different tool.
Prerequisites
- A LeadOcean account on the Free plan: 1,000 records for life, no card, 5 requests a second. Sign up here.
- For the REST steps: an API key exported as
$LEADOCEAN_API_KEY, andcurl. - For the MCP steps: Claude Desktop, Claude Code or any client that supports remote MCP with OAuth. The server URL is
https://api.leadocean.io/mcp. You sign in with OAuth and paste no key.
Step 1: Connect the MCP server
Add LeadOcean as a remote MCP server. In Claude Code:
claude mcp add --transport http leadocean https://api.leadocean.io/mcpYour client opens an OAuth sign-in. Approve it. The server exposes 13 tools. Seven cost nothing: leadocean_count_leads, leadocean_count_companies, leadocean_list_filters, leadocean_list_enum_values, leadocean_get_account, leadocean_get_export and leadocean_list_exports. search_leads, get_lead, find_phone, get_company, search_companies and export_leads spend records.
Step 2: Size the audience for free
Ask before you pull. A count never spends a record.
Use leadocean_count_leads: jobLevel VP, jobFunction "Sales & Business Development",
country CA. Do not fetch any people.The tool call behind that prompt:
{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["CA"],
"facets": false
}Enum values are exact strings. If a filter returns nothing, ask leadocean_list_enum_values for the right spelling before you guess.
Step 3: Pull the profiles
Now ask for a small page. This spends records, so keep the limit low while you test.
Use leadocean_search_leads with the same filters and limit 2.
Show name, title, company and LinkedIn URL.The REST equivalent. The body is flat JSON and filters are arrays:
curl -s https://api.leadocean.io/v1/people/search \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["CA"],
"limit": 2
}'Search pages with cursor, at 1 to 100 rows a page. One search pages to 10,000 rows. Narrow the filters instead of walking further.
Step 4: Enrich one LinkedIn URL
You already have a profile URL and want the record behind it. Enrich takes exactly one of linkedin_url, email, phone or person_id.
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
}'A person we hold nothing for returns 404 and costs nothing. Since October 2026 the response also carries career history under resume_data: past roles, educations, certifications and awards, each when held. Past employers have no company_id yet.
In Claude, say: "Use leadocean_get_lead on this LinkedIn URL and summarize the last three roles." That call costs 1 record if a profile is found and nothing if not.
Step 5: Add a phone number, only if you need it
Phones are a separate call: GET /v2/people/phone. A v2 contact call costs one record even when it finds nothing, so enrich first and ask for a phone only on the people who matter.
curl -s "https://api.leadocean.io/v2/people/phone?linkedin_url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fjane-doe-example" \
-H "x-api-key: $LEADOCEAN_API_KEY"The endpoint takes one of linkedin_url, person_id or contact_id as a query parameter. It returns the numbers best first, each with phone and type, or found: false.
Step 6: Export the whole list
When the count looks right, export instead of paging. Exports take up to 50,000 rows a request and 500,000 a day. Bulk CSV export is not on Free, so this step needs Solo ($97 a month) or higher.
curl -s https://api.leadocean.io/v1/exports \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["CA"]
},
"limit": 5000
}'The export body nests the search filters under filters, with limit beside them. Every row costs one record.
You can also do this from app.leadocean.io: the Exports page has a filter builder, a column picker and a price preview before you download the CSV.
What you get
This is the real output of the free count in Step 2, run on 2026-10-21:
{
"total": 5574,
"totalIsExact": true,
"totalAll": 18800,
"distinctCompanies": 3873,
"credits": 0
}Read it carefully. total counts people with a verified, catch-all-valid or catch-all email, the default. totalAll is the same filters with no email condition. The call spent 0 records.
The enrich response has this outline. Response shape from the API reference, with placeholder values:
{
"success": true,
"data": {
"profile_data": { "profile_full_name": "Jane Doe" },
"contact_data": {
"has_email": true,
"email_status": "verified",
"contact_current_experiences": [ { "company_name": "Acme" } ]
},
"resume_data": { "experiences": [], "educations": [] }
}
}The current role sits in contact_current_experiences[]. Past roles sit in resume_data, each when held. Fetch api.leadocean.io/openapi.json once and map the fields you need.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key, or the MCP sign-in expired | Re-export $LEADOCEAN_API_KEY or re-run the OAuth sign-in |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Wait for the Retry-After header, or slow the loop |
| 402 | The 1,000 free records are spent | Move to Solo or Agency; a 402 costs nothing |
| 404 on enrich | We hold nothing for that person | Nothing to fix and nothing charged; try the email or person_id |
| Empty results | An enum value is misspelled, for example vp instead of VP | Look it up with leadocean_list_enum_values |
| Export refused | Over 50,000 rows a request or 500,000 a day, or you are on Free | Narrow the filters, split the job, or upgrade |
FAQ
Can LeadOcean scrape LinkedIn posts?
No. It does not return posts, comments or reactions. It returns profile, role, company and contact data from its own database.
Is this a scraper?
No. Nothing is fetched from LinkedIn when you call it. The dataset is refreshed monthly and each record carries its own fetched_at date.
How many records does the walkthrough spend?
About 3: two search results and one enrichment. Counts and filter lookups spend none.
Which LinkedIn lookups already have a recipe?
Going from a profile to an email is covered in LinkedIn to email over MCP. The reverse is email to LinkedIn over MCP.
Where do I compare scraper tools?
See the LinkedIn scraper roundup. For plans and pacing, see pricing.
Pull LinkedIn profile data without running a scraper
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →