Spend month 1 sizing your market, month 2 on a 100-contact pilot, and month 3 on scaling only what got replies. This guide gives you the queries for each stage.
TL;DR
- Month 1: size the market with free count calls, lock one ICP, and spend no records.
- Month 2: pull 100 contacts, enrich the people who reply, and track reply rate by segment.
- Month 3: export the winning segment in bulk. Setup takes about 2 hours and the pilot spends about 120 of the 1,000 Free records.
Prerequisites
- A LeadOcean account on the free plan (no card): app.leadocean.io/register.
- An API key exported as
$LEADOCEAN_API_KEY. curlandjq, or any HTTP client.- A sending tool of your choice. This plan covers the data side only. LeadOcean has no sequencer, dialer or CRM.
Step 1: Size your market before you write a line of copy (weeks 1 to 2)
Run counts first. A count is free, so you can test twenty versions of your ICP and spend nothing.
Send count=true as a query parameter with limit=1. The filters go in a flat JSON 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 '{
"jobFunction": ["Sales & Business Development"],
"jobLevel": ["VP"],
"country": ["US"],
"employeeRange": ["51-200"]
}' | jq '.meta'meta.total is capped at 100,000, and data comes back empty. If you use the MCP server, leadocean_count_leads does the same job and also reports how many employers the people span.
Write down three candidate ICPs and their counts. Pick the one with the smallest total that still gives you at least a few thousand mailable people. A narrow list beats a big one in month 1.
Step 2: Fix your filter values (week 2)
Enum filters take exact strings. A wrong value returns nothing, so resolve them before you build the list.
curl -s "https://api.leadocean.io/v1/enums/job_level" -H "x-api-key: $LEADOCEAN_API_KEY" | jqJob levels are C-Team, VP, Director, Manager, Staff and Other. Seniority is lowercase (c_suite, vp, director). Job functions look like Sales & Business Development. Industry has 534 values, so search them rather than guessing. In the MCP server, call leadocean_list_enum_values with name: "industry" and a q.
Save the final filter set in a file called icp.json. It is the single source of truth for the next ten weeks.
Step 3: Pull a 100-contact pilot (weeks 3 to 4)
Pull one page of 100 and nothing more. The pilot tells you whether the message works, which a big list cannot.
curl -s -X POST "https://api.leadocean.io/v1/people/search" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobFunction": ["Sales & Business Development"],
"jobLevel": ["VP"],
"country": ["US"],
"employeeRange": ["51-200"],
"emailStatus": ["verified"],
"limit": 100
}' > pilot.jsonThis spends 100 records, because one record is one person you receive. Filtering to verified keeps bounces low. LeadOcean does not refund bounced emails, so read contact_data.email_status before you send.
Split the pilot into two groups of 50 by one variable only: the opening line, or the title. Send both for two weeks.
Step 4: Enrich the people who reply (month 2)
Enrich only the contacts who engage. Enrichment takes exactly one of linkedin_url, email, phone or 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_PILOT"}' | jqTake the id from the pilot row at meta.source_ids.person_id.
A person we hold nothing for returns 404 and costs nothing. Since October 2026 the response also carries career history (resume_data: past roles, education, certifications, awards), which is useful for the follow-up. Past employers have no company_id yet.
For a phone number on a warm reply, call GET /v2/people/phone. Check the call cost first: v2 contact endpoints cost one record per call, including a call that finds nothing.
Step 5: Review weekly and keep a scorecard (month 2)
Track four numbers per segment each week: sent, bounced, replied, meetings booked. Keep it in a plain file.
week,segment,sent,bounced,replied,meetings
5,vp-sales-us-51-200,50,2,3,1
5,vp-sales-us-51-200-b,50,1,5,2The example rows are placeholders. Replace them with your own numbers. A segment earns a bigger list only after it clears your reply bar twice in a row. Set that bar in week 5 and do not lower it later.
Step 6: Export the winner in bulk (month 3)
Export once a segment has proven itself. Bulk CSV export is not on Free, so this is where you move to Solo ($97 a month) or Agency ($497 a month, for teams).
The simplest route is the Exports page in the app at app.leadocean.io. It has a filter builder, a column picker, a price preview before you start, and a CSV download. Paste the filters from icp.json.
Through the API, POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. Request numbered columns such as email_1_address and email_1_status so you can filter on status before sending. See pricing for what each plan includes.
What you get
A count for the Step 1 ICP, run through the free MCP tool on 2026-10-21:
{
"total": 18567,
"totalIsExact": true,
"totalAll": 60456,
"distinctCompanies": 12192,
"credits": 0
}Filters: jobFunction Sales & Business Development, jobLevel VP, country US, employeeRange 51-200. The total counts mailable people (verified, catch_all_valid or catch_all). totalAll is the same filters with no email condition. The call spent no records.
A paged search returns a meta block like this (response shape from the API reference, placeholder values):
{
"success": true,
"data": [
{
"profile_data": { "profile_full_name": "Jane Doe", "profile_headline": "VP Sales at Acme" },
"contact_data": { "has_email": true, "email_status": "verified" },
"meta": { "source_ids": { "person_id": "1234567" } }
}
],
"meta": { "count": 100, "limit": 100, "credits": 100, "nextCursor": "opaque-token" }
}One search pages to 10,000 rows. When meta.depthCapped is true, narrow the filters instead of paging further.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key header | Re-export $LEADOCEAN_API_KEY and check the header name. |
| 429 | Above the plan's rate limit (5 requests a second on Free, 200 on Agency) | Honour the Retry-After header and slow the loop. |
| 402 | Records spent (1,000 for life on Free) | Move to a paid plan or narrow the pull. Counts and 404s cost nothing. |
| Empty results | Bad enum value, such as Vice President instead of VP | Resolve values with GET /v1/enums before searching. |
| Search stops early | The 10,000-row depth cap (meta.depthCapped) | Add filters and run several narrower searches. |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the export by country or headcount band. |
FAQ
How many contacts should I send in the first month?
None. Month 1 is sizing and message drafting. Send the 100-contact pilot in weeks 3 to 4, once the ICP is fixed.
Do I need a paid plan to follow this?
No. The whole pilot fits in the Free plan's 1,000 records. You need a paid plan at the export stage in month 3.
Why filter on verified email?
Bounces hurt your sending domain and early data. Verified addresses keep the pilot readable. Widen to catch_all once the message works.
Where does this fit with automation?
Automate after the pilot works, not before. See how to automate outbound sales and the outbound sales automation hub.
Is this plan only for large teams?
No. B2B outbound for B2B teams covers team setups. One person can run this plan alone.
Size your first outbound market for free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →