Buy leads in three moves: size the list, test a sample, then export. Most sellers skip the first two and sell you a CSV. Do them yourself and you pay for rows you have already seen.
TL;DR
- Count the list before you buy it. A count is free on LeadOcean and takes one request.
- Pull 25 rows and check them. That takes about 30 minutes and spends 25 records.
- Export only mailable rows. Read
email_statusbefore you send, because bounced emails are not refunded.
Prerequisites
- A LeadOcean account. The Free plan is $0 with 1,000 records for life and no card.
- An API key in your shell:
export LEADOCEAN_API_KEY=... curlandjq. Nothing else.
A note on where leads come from. You can buy from a list seller, a data API, a platform with a rep workspace, or build from public sources yourself. A one-off list goes stale, and a one-off CSV does not tell you what you are paying per usable row. An API with a free count lets you test the claim before you spend. For a ranked comparison of vendors, see best lead database.
Step 1: Write the filter as data
Define who you want as a filter, not a paragraph. Filters are arrays of strings, and enum values are exact strings.
curl -s "https://api.leadocean.io/v1/enums/job_function" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq '.data[:5]'The same filter set drives search, count and export. Here is ours: VP-level sales leaders in the US.
{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"]
}Wrong casing returns an empty result, not an error. Check the value with the enums endpoint or the leadocean_list_enum_values MCP tool, which is free.
Step 2: Count it for free
A count costs nothing. Send count=true as a query parameter with limit=1. Do not put it in the JSON body, which rejects unknown fields.
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"]}' \
| jq '.meta'meta.total is capped at 100,000 on this route. The MCP tool leadocean_count_leads runs the same count and adds a breakdown by industry and company size.
Step 3: Separate mailable from total
The total is not the list you can send to. leadocean_count_leads counts only verified, catch_all_valid and catch_all addresses by default, and reports the unfiltered total next to it.
| Filter | Count | Date |
|---|---|---|
| Mailable (verified, catch_all_valid, catch_all) | 129,494 | 2026-10-21 |
Same filters, no email condition (totalAll) | 350,517 | 2026-10-21 |
Those are the same filters, run through leadocean_count_leads. The mailable count is the number to buy against. A seller who quotes you the larger figure is selling you rows you cannot send to.
Step 4: Pull 25 rows and inspect them
Now spend 25 records. Add emailStatus so the sample shows only rows you would send to. Add an industry or an employee range too if your spec has one.
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"],
"emailStatus": ["verified"],
"limit": 25
}' | jq '.meta'Check the rows by hand. Are titles current? Do the companies fit? Look at meta.nextCursor to see that paging works. One search pages to 10,000 rows (meta.depthCapped turns true), so narrow the filter instead of walking further.
To get the contact data for one person, enrich by the person_id the search row carries at meta.source_ids.person_id. It costs one record, and a miss is a free 404.
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","reveal_email":true}'Step 5: Export the rows you keep
When the sample looks right, export. POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. It is async: you poll, then download. Bulk CSV export is not on Free. It is included on Solo ($97 a month) and Agency ($497 a month, 50k rows a file).
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-vp-sales",
"filters": {
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"],
"emailStatus": ["verified"]
},
"limit": 5000,
"preset": "full"
}'Poll GET /v1/exports/{id}. When it is done, fetch GET /v1/exports/{id}/download. The app has the same flow without code: the Exports page at app.leadocean.io has a filter builder, a column picker and a price preview before you start.
What you get
The count from Step 3 is real output, run on 2026-10-21 with the leadocean_count_leads tool:
{
"total": 129494,
"totalIsExact": true,
"totalAll": 350517,
"distinctCompanies": 58121,
"credits": 0
}credits: 0 is the tool's own field name, and the call spent no records. Below is the response shape from the API reference (openapi.json, October 2026) for a search row, with placeholder values.
{
"success": true,
"data": [
{
"profile_data": {
"profile_full_name": "Jane Doe",
"profile_headline": "VP Sales at Acme"
},
"contact_data": { "has_email": true, "has_phone": true, "email_status": "verified" },
"meta": { "source_ids": { "person_id": "1234567890" } }
}
],
"meta": { "count": 1, "limit": 25, "nextCursor": "CURSOR", "depthCapped": false }
}An export CSV carries email_1_address, email_1_status and phone_1_number columns. Filter on email_1_status before you load a sequencer.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key | Check $LEADOCEAN_API_KEY is exported and sent as the x-api-key header |
| 429 | Above the plan's rate limit (5 a second on Free, 50 on Solo, 200 on Agency) | Back off and honor Retry-After |
| 402 | Out of records | Free is 1,000 for life. Move to a paid plan |
| Empty results | A bad enum value, such as vp for jobLevel | Look up the exact string with /v1/enums or leadocean_list_enum_values |
400 export_limit_rows | More than 50,000 rows in one export | Split the filter into several exports |
429 export_limit_daily | Past 500,000 export rows in a day | Wait for resetsAt in the response |
FAQ
Is it legal to buy a lead list?
That depends on where the people sit and how you contact them. This is not legal advice. Ask your counsel before a campaign, and keep an unsubscribe path in every email.
How much does it cost to buy leads?
On LeadOcean the Free plan spends 1,000 records once. Solo is $97 a month and Agency is $497 a month, on a fair-use pace, with no per-record price. See pricing.
Do bounced emails get refunded?
No. Read email_status and send only to verified rows.
How fresh is the data?
The dataset is refreshed monthly. Each record also carries its own fetched_at date.
What if I already have a list?
Enrich it instead of buying a new one. See B2B lead enrichment to data collection. For contact-only databases, see best B2B contact databases.
Count your own list free, then sample 25 rows
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →