Prospecting with B2B data is four moves: size the list, search it, enrich the people worth the spend, and export the rest. Do them in that order and you never pay for a list you did not size first.
TL;DR
- Count first, for free. A count, a breakdown and an empty page cost 0 records, so you can tune filters until the audience is the right shape.
- Pull one page of 25 people, enrich 5 of them, and export the remainder once the filters hold.
- The run below takes about 30 minutes and spends about 30 records, well inside the Free plan's 1,000 records for life.
Prerequisites
- A LeadOcean account on the Free plan (no card). Create one at app.leadocean.io and copy a key from the API keys page.
- The key in your shell as
$LEADOCEAN_API_KEY. Free allows 5 requests a second, so run the steps one at a time. curlandjq. Nothing else.
export LEADOCEAN_API_KEY="paste-your-key-here"Step 1: Write the ICP as filters
Turn the persona into closed-list filters before you call anything. Enum values are exact strings, so look them up instead of guessing.
curl -s "https://api.leadocean.io/v1/enums" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq 'keys'Our example persona: VPs of sales at US software companies with 51-200 staff.
| Persona word | Filter | Value |
|---|---|---|
| VP | jobLevel | VP |
| Sales | jobFunction | Sales & Business Development |
| US | country | US |
| 51-200 staff | employeeRange | 51-200 |
Company-side, add industry: ["Software Development"]. The industry list has 534 values, and older labels such as Computer Software match far fewer companies, so resolve yours before use. The same lookup is the MCP tool leadocean_list_enum_values, which is free.
Step 2: Size the list for free
Send count=true as a query parameter with limit=1. The JSON body rejects unknown fields, so the flag does not go in the body.
curl -s -X POST "https://api.leadocean.io/v1/people/search?count=true&limit=1" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "content-type: application/json" \
-d '{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"],
"employeeRange": ["51-200"]
}' | jq '.meta'meta.total is capped at 100,000 and data comes back empty with meta.countOnly true. Size the companies the same way with GET /v1/companies/count, which returns an exact total and breakdowns by industry, headcount band, HQ country, HQ state and NAICS.
Step 3: Pull a page and read the fields
Drop the count flag and set a real limit. Limit runs 1 to 100, and the default is 25.
curl -s -X POST "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
}' > page1.json
jq '.meta' page1.jsonThis spends 25 records, one per person returned. To get the next page, pass the nextCursor from meta as cursor. One search pages to 10,000 rows. At that point meta.depthCapped is true and there is no nextCursor, so narrow the filters instead of walking the index.
Step 4: Enrich only the people you will contact
Search gives you the person. Enrich gives you the contact detail and career history. Enrich takes exactly one of linkedin_url, email, phone or person_id. There is no name plus domain lookup, so search first and enrich by person_id.
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": "PERSON_ID_FROM_PAGE1", "reveal_email": true}'reveal_email costs no extra record. A person we hold nothing for is a 404 and costs nothing. Since October 2026 the response also carries career history in resume_data: past roles, education, certifications and awards, when held. Past employers have no company_id yet.
Need a phone? GET /v2/people/phone returns it, and v2 contact endpoints cost one record per call even on a miss. Read email_status before you send. Bounced emails are not refunded.
Step 5: Export the audience once the filters hold
Bulk CSV export is not on Free. On Solo ($97 a month) and above, POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. On Free, use the search pages from Step 3, or the Exports page in the app, which shows the record price before you start.
curl -s -X POST "https://api.leadocean.io/v1/exports" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "content-type: application/json" \
-d '{
"name": "US sales VPs, 51-200",
"filters": {
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"],
"employeeRange": ["51-200"]
},
"limit": 5000
}'Poll GET /v1/exports/{id} until it is done, then fetch GET /v1/exports/{id}/download. Every row costs one record.
Numbered columns are requested as email_N_address, email_N_status and phone_N_number. The CSV headers come back as email_1_address, email_2_address and so on.
What you get
These are live results from the free MCP tools on 2026-10-21. No records were spent.
People count for jobLevel VP, jobFunction Sales & Business Development, country US, employeeRange 51-200 (mailable by default: verified, catch_all_valid or catch_all):
{
"total": 18567,
"totalIsExact": true,
"totalAll": 60456,
"distinctCompanies": 12192
}total is the mailable audience. totalAll is the same filters with no email condition. The gap is the list you would have paid for and could not send to.
Company count for industry Software Development, hqCountry US, employeeRange 51-200: 9,261 companies, 2,398 of them HQ'd in California and 842 in New York.
The record-level search response has this shape (response shape from the API reference, placeholder values only):
{
"success": true,
"data": [
{
"profile_data": {
"profile_full_name": "Jane Doe",
"profile_headline": "VP of Sales at Acme"
},
"contact_data": {
"has_email": true,
"email_status": "verified",
"email_type": "work",
"contact_current_experiences": [
{ "company_name": "Acme", "company_domain": "acme.com", "job_title": "VP of Sales" }
]
},
"meta": { "source_ids": { "person_id": "1234567890" } }
}
],
"meta": { "count": 25, "credits": 25, "nextCursor": "eyJ..." }
}Search rows carry no contact points. meta.source_ids.person_id is the key you send to enrich in Step 4.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key header | Check $LEADOCEAN_API_KEY is exported and sent as x-api-key. |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Honor the Retry-After header, or upgrade the plan. |
| 402 | Out of records (Free is 1,000 for life) | Add a plan at leadocean.io/pricing. Counts still work. |
Empty data on a search | Bad enum value, such as Vice President instead of VP | Look the value up with /v1/enums or leadocean_list_enum_values. |
| 404 on enrich | We hold nothing for that person | Nothing is charged. Try another identifier. |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the audience with narrower filters. |
FAQ
How many records does prospecting cost?
One record is one person or one company you receive. A search page of 25 is 25 records. Counts, breakdowns, empty pages and enrichments that find nothing cost 0.
Should I enrich everyone I search?
No. Search first, then enrich only the people you will contact. It keeps the spend on the people who matter. The dataset is refreshed monthly, and each record carries its own fetched_at date.
Does LeadOcean replace my sequencer or CRM?
No. LeadOcean is data and an API with an app for exports. It has no sequencer, dialer, CRM or Chrome extension, so send the output to the tool you already use.
Can I run this from an AI assistant?
Yes. The hosted MCP server at https://api.leadocean.io/mcp exposes 13 tools. leadocean_count_leads and leadocean_count_companies size a list for free.
Where do I go next?
Compare sources in best lead database. Automate the loop with prospecting automation. For the difference between the two jobs, read lead generation or prospecting. Plans are on the pricing page, and more guides are on the blog.
Size your own prospect list for free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →