Size the segment with a free count. Pull the matching people. Upload the CSV as a Matched Audience. This guide does it with real filters and the real output of a free count run on 2026-10-21.
TL;DR
- Build the audience in about 20 minutes: count, pull, export, upload.
- Sizing is free. A test pull of 100 people spends 100 of your 1,000 free records.
- Use company lists when the buyer is the account, and people lists when the buyer is a role.
Prerequisites
- A LeadOcean API key from the free plan, exported as
$LEADOCEAN_API_KEY. Free is 1,000 records for life, no card, 5 requests a second. curlandjq.- A LinkedIn Campaign Manager account with permission to create Matched Audiences.
- Optional: the LeadOcean MCP server, if you would rather size the audience from Claude. The tool is
leadocean_count_leads.
Step 1: Pick the filters that match your ad targeting
Match the list to the offer, not to the widest audience you can find. LinkedIn already lets you target by job title and company size, so the reason to bring your own list is control: named accounts, verified contacts, and exclusions LinkedIn cannot do.
Our example: VPs and C-level marketers at US software companies with 51 to 500 employees.
Enum values are exact strings. Check them before you guess.
curl -s "https://api.leadocean.io/v1/enums" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq 'keys'The values used below are jobLevel VP and C-Team, jobFunction Advertising & Marketing, industry Computer Software, and employeeRange 51-200 and 201-500. The MCP tool leadocean_list_enum_values resolves any of them for free.
Step 2: Size the audience before you spend anything
A count costs zero records. Send count=true as a query parameter with limit=1. The body stays flat JSON and every filter is an array.
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", "C-Team"],
"jobFunction": ["Advertising & Marketing"],
"country": ["US"],
"industry": ["Computer Software"],
"employeeRange": ["51-200", "201-500"]
}' | jq '.meta'meta.total is capped at 100,000 on this call. If you hit the cap, narrow the filters. For company-level sizing use GET /v1/companies/count, which is also free and returns breakdowns by industry, headcount band and HQ state.
Keep the size in context. LinkedIn needs at least 300 rows to accept a contact list. The list must then match 300 member accounts before an ad set can use it (LinkedIn help: contact list targeting, October 2026). A list of 46 people will not run. Widen to Director level or drop the headcount filter until the count is in the thousands.
Step 3: Pull a test page
Pull 100 people to look at the data before you export the whole audience. This spends 100 records.
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", "C-Team"],
"jobFunction": ["Advertising & Marketing"],
"country": ["US"],
"industry": ["Computer Software"],
"employeeRange": ["51-200", "201-500"],
"limit": 100
}' > page1.json
jq '.meta' page1.jsonTo read the next page, send cursor with the value from meta.nextCursor. One search pages to 10,000 rows. When meta.depthCapped is true there is no nextCursor, so split the audience by country or headcount band instead of walking further.
Read email_status on each record before you decide what to upload. If you also mail the list, we do not refund bounces, so filter on status first.
Step 4: Export the full audience as a CSV
For anything past a test page, use an export. In the app at app.leadocean.io, open the Exports page, build the same filters, pick the columns, check the price preview, and download the CSV. The same job runs from the API with POST /v1/exports, up to 50,000 rows a request and 500,000 rows a day. Bulk CSV export is not on Free. It is included on Solo ($97 a month).
Ask for the columns LinkedIn matches on: first name, last name, email, job title and company name. Column ids come from GET /v1/exports/columns.
curl -s -X POST "https://api.leadocean.io/v1/exports" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "content-type: application/json" \
-d '{
"name": "linkedin-us-software-marketing",
"filters": {
"jobLevel": ["VP", "C-Team"],
"jobFunction": ["Advertising & Marketing"],
"country": ["US"],
"industry": ["Computer Software"],
"employeeRange": ["51-200", "201-500"]
},
"limit": 5000,
"columns": ["profile_first_name", "profile_last_name", "email_N_address",
"current_job_title", "current_company_name"],
"caps": { "emails": 1 }
}'The answer is a job id. Poll GET /v1/exports/{id} until status is done, then download the file. With one email cap the CSV header comes back as email_1_address, in column 3.
Then clean the file.
awk -F, 'NR==1 || ($3 != "" && !seen[$3]++)' export.csv > linkedin-upload.csvChange the column number if you reorder the columns. A spreadsheet works too, as long as each email appears once.
Step 5: Upload to Campaign Manager
Download the CSV template in Campaign Manager and paste your rows under its headers. LinkedIn rejects a file whose template headers were changed or removed, and the email column header must be email. It matches on email, or on first and last name plus company name. A list can take up to 48 hours to build (LinkedIn help, October 2026).
LinkedIn recommends uploading at least 10,000 email addresses so the list matches at least 300 members (same source). Compare the matched count with your file before you set a budget.
Two habits save budget:
- Upload accounts, not people, when the offer is sold to a buying committee. Pull company domains with
POST /v1/companies/searchand upload a company list. - Refresh monthly. The dataset refreshes monthly, and each record carries its own
fetched_atdate. Stale lists lose match rate.
Step 6: Layer exclusions so you stop paying for the wrong people
Build a second list of people to skip. Think current customers, open opportunities and your own staff. Upload it as its own Matched Audience, then exclude it in the campaign. Export your customers from your CRM and keep the same email column.
Exclusion lists pay for themselves. Every impression spent on a customer is an impression not spent on a prospect.
What you get
This is the output of the free MCP tool leadocean_count_leads for the Step 2 filters, run on 2026-10-21. It spent zero records.
{
"total": 46,
"totalIsExact": true,
"totalAll": 132,
"distinctCompanies": 31,
"distinctCompaniesIsExact": true,
"credits": 0,
"defaults": "Counted only addresses worth sending to (emailStatus: verified or catch_all_valid or catch_all)",
"unsupportedFilters": []
}Read it carefully. The 46 is a mailable count: people with a verified, catch-all-valid or catch-all email, at 31 companies. Without an email condition the same filters match 132 people (totalAll).
The company side comes from leadocean_count_companies, same date, US HQ, 51 to 500 employees, Computer Software:
{
"total": 728,
"totalIsExact": true,
"facets": {
"employee_range": [
{ "value": "51-200", "count": 460 },
{ "value": "201-500", "count": 268 }
],
"hq_state": [
{ "value": "California", "count": 204 },
{ "value": "Massachusetts", "count": 51 },
{ "value": "New York", "count": 51 }
]
},
"credits": 0
}The lesson is plain. There are 728 target companies but only 46 mailable VP and C-level marketers. For a LinkedIn list that is a small audience. Computer Software is also an older industry label, so add Software Development to widen. Or widen the level to Director, or upload the 728 as a company list and let LinkedIn's own targeting pick the roles. A company list also needs at least 300 rows.
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 requests a second on Free, 200 on Agency) | Wait for the Retry-After seconds, then slow the loop |
| 402 | Out of records | Free is 1,000 records for life, so move to Solo ($97 a month) or Agency ($497 a month) |
| Empty results | A filter value is not an exact enum string | Look it up with /v1/enums or leadocean_list_enum_values |
meta.depthCapped true, no nextCursor | One search reached 10,000 rows | Split by country or headcount band and run each slice |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the export into several requests |
FAQ
Do I need the API, or can I use the app?
The app is enough for one list. Its Exports page has a filter builder, a column picker and a price preview, then a CSV download. Use the API when you rebuild the list on a schedule.
How big should a LinkedIn Ads audience be?
The floor is 300 matched member accounts per ad set, and LinkedIn suggests uploading at least 10,000 emails to reach it (LinkedIn help, October 2026). Count first, then decide whether to widen.
What does a lookalike audience have to do with this?
LinkedIn can build one from your uploaded list. Read the lookalike audiences glossary entry for what that means and when it helps.
Can Claude size the audience for me?
Yes. The audience sizer skill calls the free count tools and returns the numbers with the filters it used. For the wider list-building workflow see list building.
What does it cost?
Build your LinkedIn Ads audience from real filters, free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →