Six API calls cover everything a recruiter needs about a candidate: how many exist, who they are, where they worked, and how to reach them. Most "enrichment tool" lists give you six vendors. This one gives you six calls on one API, with the request, the record cost and the failure mode for each.
The calls run in this order: count, search, enrich, work email, phone, reverse lookup. You can stop after any step. Step 1 costs nothing. Every other step costs one record per person or call.
TL;DR
- Six requests against
https://api.leadocean.io: size the list, search it, enrich one person, then pull work email, phone and reverse lookups as needed. - Time: about 20 minutes to wire up, then each call returns in a request. You run them from curl, a script or an MCP client.
- Records: sizing is free. One candidate end to end costs 3 to 8 records, depending on how many of the contact calls you run.
Prerequisites
- A LeadOcean API key in
$LEADOCEAN_API_KEY. The Free plan gives 1,000 records for life, no card, 5 requests a second (sign up). curlandjq.- A candidate profile URL. Examples use the placeholder
https://www.linkedin.com/in/janedoe-exampleand the person_id1234567890.
Step 1: Size the pool for free
Start with a count so you know the pool before you spend a record. The MCP tool leadocean_count_leads is free, and so is the REST search with count=true and limit=1. Send count=true as a query parameter, not in the JSON body.
curl -s -X POST "https://api.leadocean.io/v1/people/search?count=true" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": ["Recruiter"], "country": ["US"], "limit": 1}'meta.total is capped at 100,000, and data comes back empty with meta.countOnly true. If the count is bigger than you can work, add a filter before step 2.
Step 2: Search for candidates
Search is a flat JSON body. Filters are arrays of strings, limit runs 1 to 100, and you page with cursor. Every row returned is one record, so keep limit small while you test.
curl -s -X POST https://api.leadocean.io/v1/people/search \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": ["Recruiter"],
"country": ["US"],
"limit": 5
}' | jq '.data[] | {name: .profile_data.profile_full_name, person_id: .meta.source_ids.person_id}'Search rows are a thin projection with no contact points. Keep the person_id. About a fifth of people have no LinkedIn URL, so person_id is the key that always works.
Step 3: Enrich one person with career history
Enrich takes exactly one of linkedin_url, email, phone or person_id. Since October 2026 it also returns career history: past roles, education, certifications and awards, each when held.
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": "1234567890"}' \
| jq '.data.resume_data.experiences'Past employers carry no company_id yet, so match them by name. The current role is in contact_current_experiences[]. A person we hold nothing for is a 404, and it costs nothing.
Step 4: Get the work email
Set reveal_email to true on enrich and the addresses come back in the same call, at no extra record. For a dedicated call, use the v2 work email endpoint with a linkedin_url or person_id.
curl -s "https://api.leadocean.io/v2/people/email/work?person_id=1234567890" \
-H "x-api-key: $LEADOCEAN_API_KEY"This endpoint costs one record per call, including a call that finds nothing. Use reveal_email on enrich when you already enrich the person. Use the v2 call when you only need the address. Read email_status before you send, because there is no refund for bounced emails.
Step 5: Get the phone number
Recruiters call. The phone endpoint takes the same identifiers as the email endpoints.
curl -s "https://api.leadocean.io/v2/people/phone?linkedin_url=https://www.linkedin.com/in/janedoe-example" \
-H "x-api-key: $LEADOCEAN_API_KEY"It costs one record per call, hit or miss. Phones are on every plan, including Free. For a longer walk through numbers, see how to find a recruiter's phone number.
Step 6: Reverse lookup an unknown email or phone
A candidate replies from an address you do not recognise, or a missed call leaves a number. The reverse endpoint tells you who holds it. Send one of email or phone.
curl -s "https://api.leadocean.io/v2/people/reverse?email=jane.doe@acme.com" \
-H "x-api-key: $LEADOCEAN_API_KEY"It costs one record, hit or miss, and returns the identity with a person_id. Enrich that person_id to get the full profile from step 3.
To run steps 3 to 5 for a short list of person_ids, loop over them and pace the loop to your plan. Free allows 5 requests a second, so sleep a quarter of a second between calls.
for id in 1234567890 1234567891 1234567892; 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 "{\"person_id\": \"$id\", \"reveal_email\": true}" \
| jq '{name: .data.profile_data.profile_full_name,
emails: [.data.contact_data.contact_emails[]? | {email, status: .status}]}'
sleep 0.25
doneThree ids with reveal_email cost three records at most. A 404 in the loop costs nothing, so a miss does not eat budget. For more than a few hundred candidates, use an export instead of a loop.
What you get
Here is the free sizing call from step 1, run through the MCP tool leadocean_count_leads on 2026-10-21. It spent 0 records.
title: ["Recruiter"], country: ["US"]
-> total 182,520, totalIsExact true, totalAll 561,886,
distinctCompanies 37,731, credits 0The total counts verified, catch_all_valid and catch_all addresses only, which is the tool's default. The 561,886 is everyone matching the filters with or without an email. The REST call in step 1 caps meta.total at 100,000, so it shows 100,000 here. The title filter is a text match, so check a page of rows before you trust the label.
The enrich response shape, from the API reference, with placeholder values:
{
"data": {
"profile_data": { "profile_full_name": "Jane Doe" },
"resume_data": {
"experiences": [
{ "job_title": "Recruiter", "company_name": "Example Co" }
],
"educations": [],
"certifications": []
},
"contact_data": {
"contact_current_experiences": [
{ "job_title": "Senior Recruiter", "company_name": "Acme" }
],
"contact_emails": [
{ "email": "jane.doe@acme.com", "type": "work", "status": "verified" }
],
"contact_phones": [
{ "phone": "+1 415 555 0133" }
]
}
}
}This is the response shape from the API reference, not a real person. Field names vary slightly by call, so read the live response once and map the fields you use.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing, wrong or revoked key | Check the x-api-key header and that $LEADOCEAN_API_KEY is set in this shell. |
| 404 on enrich | Nobody matched, or nothing is held | Free. Try another identifier, or search by domain first and enrich by person_id. |
Empty search data | A filter value is not an exact enum string | Check values with leadocean_list_enum_values or GET /v1/enums. |
| 429 | Above your plan's rate limit (5 a second on Free, 200 on Agency) | Wait for Retry-After and retry. |
| 402 | Free plan: the 1,000 records are spent | They do not reset. Move to Solo at $97 a month, or Agency at $497 (pricing). |
| Export refused | Over 50,000 rows a request or 500,000 a day, or on the Free plan | Split the export into smaller filters. Bulk CSV is not on Free. |
FAQ
Do I need all six calls for every candidate?
No. Most roles need steps 2, 3 and 4. Add the phone call only for candidates you will ring, because each v2 contact call costs one record whether or not it finds anything.
How many records does one candidate cost?
A search row is one record. Enrich with reveal_email is one more, and a miss is free. Each v2 email or phone call is one record, hit or miss. A full run lands at 3 to 8 records.
Can I send hundreds of candidates at once?
Yes, through exports. POST /v1/exports takes up to 50,000 rows a request and 500,000 a day, with bulk CSV on Solo and above. The app at app.leadocean.io has an Exports page with a filter builder and a price preview. It is not a recruiting workspace: there is no sequencer, dialer or CRM.
Can an AI agent run these calls?
Yes. The hosted MCP server at https://api.leadocean.io/mcp signs in with OAuth and has 13 tools, including leadocean_count_leads, which is free. Tools that return people spend records exactly as the REST calls do.
Where do I compare vendors?
Find your first candidate's career history, email and phone for free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →