Sales personalization tools write the sentence. The sentence is only as good as the fact you hand them. This guide builds the fact layer: a list of prospects, each with one verifiable detail from their career.
TL;DR
- Search one segment, enrich each person, and keep one career fact per row. It takes about 30 minutes for 25 prospects.
- It spends about 50 LeadOcean records for 25 prospects: 25 from the search, 25 from the enrich calls. The Free plan has 1,000 records for life.
- Size the list first with the free count. Sizing spends nothing.
Prerequisites
- A LeadOcean API key in
$LEADOCEAN_API_KEY. Free works: no card, every feature, 1,000 records. curlandjq.- Any tool that takes a CSV and writes the email: a sequencer, a spreadsheet, or an LLM prompt. This guide stops at the data.
Step 1: Size the list for free
Count before you pull. A count spends no records, so run it as often as you like.
In Claude or any MCP client connected to https://api.leadocean.io/mcp, call leadocean_count_leads:
{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"],
"employeeRange": ["51-200"],
"facets": false
}On 2026-10-21 this returned 18,567 people with a verified, catch_all_valid or catch_all email, across 12,192 companies. Without any email condition the same filters match 60,456.
Enum values are exact strings. If a filter returns nothing, check the spelling with leadocean_list_enum_values.
Step 2: Pull a small segment
Search the segment with a limit of 25. The body is flat JSON and every filter is an array.
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": ["US"],
"employeeRange": ["51-200"],
"limit": 25
}' | tee search.json | jq '.meta'Each person returned costs one record. For more rows, pass the cursor from the previous page. One search pages to 10,000 rows, then meta.depthCapped is true. Narrow the filters instead of walking further.
Step 3: Enrich each person for career history
Search finds the person. Enrich returns the history. Enrich takes exactly one of linkedin_url, email, phone or person_id, so use the person_id each search row carries at meta.source_ids.person_id.
jq -r '.data[].meta.source_ids.person_id' search.json | while read id; do
curl -s 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}" \
> "enrich_$id.json"
sleep 0.3
doneEnrich returns resume_data with past roles, education, certifications and awards, each when the person has them. An enrich that finds nobody is a 404 and costs nothing. The sleep keeps you under 5 requests a second on Free.
Step 4: Pick one fact per person
A good personalization line is one true, checkable detail: a previous employer, a title change, a school. Each past role carries a title, company name, start and end dates and job level, when held (enrich docs, October 2026). Print a few entries and read the keys before you map them to CSV columns.
for f in enrich_*.json; do
jq -c '.data | {
now: .contact_data.contact_current_experiences[0],
before: .resume_data.experiences[0:2]
}' "$f"
doneRules that keep the line honest:
- Use a past employer only if the dates are present.
- Skip anyone with an empty
experienceslist. Do not guess. - One fact per email. Two reads as a dossier.
Step 5: Hand the fact to your writing tool
Write the CSV with email, first_name, fact and source_field. Then give your tool a prompt that cannot invent.
Write a 2-sentence opening for a cold email to {first_name}.
Use only this fact: {fact}
Do not mention anything not in the fact. No flattery. No questions.Check contact_data.email_status before you send. LeadOcean does not refund bounces.
What you get
The count in Step 1, run on 2026-10-21, returned:
{
"total": 18567,
"totalIsExact": true,
"totalAll": 60456,
"distinctCompanies": 12192,
"unsupportedFilters": []
}Total is the mailable audience. The enrich response shape from the API reference, with placeholder values:
{
"success": true,
"data": {
"profile_data": { "profile_full_name": "Jane Doe", "profile_headline": "VP Sales at Acme" },
"contact_data": {
"email_status": "verified",
"contact_current_experiences": [
{ "job_title": "VP Sales", "company_name": "Acme", "company_domain": "acme.com" }
]
},
"resume_data": { "experiences": [], "educations": [], "certifications": [] }
},
"meta": { "schema": "leadocean.person.v1" }
}The arrays are empty in this placeholder. On a real record, experiences holds one object per past role. If you would rather not parse JSON, the export column picker has past_N_job_title, past_N_company_name, past_N_start_date and past_N_end_date, though bulk CSV export needs a paid plan.
Past employers carry no company_id yet, so match them by name.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key | Check $LEADOCEAN_API_KEY is exported and the header name is exact |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Honor Retry-After, or add a sleep |
| 402 | Records spent | Free is 1,000 for life. Move to Solo at $97 a month or Agency at $497 a month |
| Empty results | Enum value spelled wrong | Resolve it with leadocean_list_enum_values |
| Search stops at 10,000 rows | meta.depthCapped is true | Narrow the filters |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the export. Bulk CSV is not on Free |
FAQ
Do I need a separate sales personalization tool?
You need something to write the sentence. That can be a sequencer, a spreadsheet formula or an LLM prompt. The data step above is the part most tools skip.
How many records does this spend?
About 2 per prospect: one in search, one in enrich. Counts, filter lists and empty enrich calls are free.
Is career history always present?
No. resume_data returns each section only when the person has it. Skip the rows without one.
Can I do this in the app instead of the API?
Partly. The Exports page in app.leadocean.io has a filter builder and a column picker with a price preview. It is on paid plans for bulk CSV.
What does it cost at volume?
Paid plans have a fair-use pace, not credits. See pricing.
Related: outbound playbooks, email personalization and how to sell to a VP of Sales. More guides are on the blog.
Get one true line per prospect, from real career data
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →