Sales Navigator has no CSV download for lead lists. The fastest clean route is to rebuild the search as API filters and pull the rows from a data source.
LinkedIn's help center says a Sales Navigator search shows up to 2,500 lead results across 100 pages (October 2026). Fullenrich's guide says the tool lacks a native export function for lead lists (October 2026).
Fullenrich names three routes: save leads to lists inside Sales Navigator, sync a CRM, or use a third-party extension such as Evaboot or Wiza (October 2026). The saved list stays inside LinkedIn. The CRM sync moves records, not a file you control.
The extensions read your browser session. They inherit the search cap and add their own daily export limit. Fullenrich puts that limit at 5,000 leads a day (October 2026). Check any extension's terms before you point it at your account.
This page skips the browser extensions. It uses filters, not the page, so there is no browser session to protect.
TL;DR
- Copy your Sales Navigator filters, rebuild them as a LeadOcean search, and size the list for free with
count=true. About 20 minutes the first time, mostly getting a key. - Sizing costs 0 records. Paging 25 rows spends 25 of your 1,000 free records. A CSV through
POST /v1/exportscosts 1 record per row. - Bulk CSV export is not on Free. Solo at $97 a month includes it. The Free plan can still page rows through search.
Prerequisites
- Your Sales Navigator search written down: titles, seniority, function, country, company size, industry.
- A LeadOcean account and key from app.leadocean.io. Free has no card.
- The key in your shell as
$LEADOCEAN_API_KEY. curlandjq. Step 6 also uses Miller (mlr) to filter the CSV.
export LEADOCEAN_API_KEY="paste-your-key-here"Step 1: Write the search as filters
Map each Sales Navigator filter to a LeadOcean filter. Enum values are exact strings, so look them up before you guess. The free GET /v1/enums/{name} call lists them.
curl -s "https://api.leadocean.io/v1/enums/job_level" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq -c '.'| Sales Navigator filter | LeadOcean filter |
|---|---|
| Seniority level: VP | jobLevel: ["VP"] |
| Function: Sales | jobFunction: ["Sales & Business Development"] |
| Geography: United States | country: ["US"] |
| Company headcount | employeeRange: ["51-200"] |
| Job title keyword | title: ["Head of Sales"] |
The body is flat JSON. Every filter is an array of strings.
Step 2: Size the list for free
Send count=true as a query parameter with limit 1. It costs 0 records and tells you the list size before you spend anything. meta.total is capped at 100,000.
curl -s -X POST "https://api.leadocean.io/v1/people/search?count=true" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "content-type: application/json" \
-d '{
"jobLevel": ["VP"],
"jobFunction": ["Sales & Business Development"],
"country": ["US"],
"limit": 1
}' | jq '.meta | {total, countOnly}'Sales Navigator shows a total too, but its results page stops at 2,500 leads, per LinkedIn's help center. Here the size is a number you can plan a budget around. The sizing call is where this beats the extension route. You see the size first, then decide whether to narrow the filters.
Read the two totals. total is the mailable audience. If it is far over what you need, add employeeRange or a second country and size again. Each call is free, so iterate until the number fits.
Step 3: Page a test sample
Pull one page of 25 to check the rows look right before Step 4 or Step 5. It spends 25 records. Paginate with cursor from the previous response.
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"],
"limit": 25
}' > page1.json
jq '.meta' page1.jsonlimit runs from 1 to 100. One search pages to 10,000 rows. On the capped page, meta.depthCapped is true and there is no nextCursor. Narrow the filters instead of walking further.
Step 4: Page the whole list on the Free plan
Bulk CSV export is not on Free, but search paging is. Loop on cursor until it is gone and write the rows to a file. Keep the limit under 5 requests a second.
cursor=""
: > rows.jsonl
for i in $(seq 1 4); do
body=$(jq -n --arg c "$cursor" '{
jobLevel: ["VP"], jobFunction: ["Sales & Business Development"],
country: ["US"], limit: 25
} + (if $c == "" then {} else {cursor: $c} end)')
resp=$(curl -s -X POST "https://api.leadocean.io/v1/people/search" \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" -d "$body")
echo "$resp" | jq -c '.data[]' >> rows.jsonl
cursor=$(echo "$resp" | jq -r '.meta.nextCursor // empty')
[ -z "$cursor" ] && break
sleep 0.25
done
wc -l rows.jsonlFour pages of 25 is 100 records. Raise the page count only after you have read rows.jsonl.
Step 5: Export the whole list to CSV
For anything beyond a few hundred rows, create an export. It runs async. One request takes up to 50,000 rows and an account takes 500,000 a day. This needs a plan with bulk CSV export, which is Solo at $97 a month or Agency at $497 a month.
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"]
},
"limit": 5000,
"preset": "search"
}' | jq '.data | {id, status, requested}'The search preset has 27 columns and no contact points. The default full preset has 45 columns, including up to 3 emails and 2 phones, and needs the enrich scope. Every row costs 1 record whatever the columns.
Poll the export, then download it. The download link is signed and opens without a key.
curl -s "https://api.leadocean.io/v1/exports/EXPORT_ID" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq '.data | {status, rows, billed, downloadUrl}'Prefer clicking? The Exports page in the app has a filter builder, a column picker, the record price before you start, and a Download button.
Step 6: Check the email status column
If you used the full preset, read each address's status before you send. Keep verified and catch_all_valid. Keep catch_all only if you accept that the domain takes any address. LeadOcean gives no refund or credit for bounced emails.
mlr --icsv --ojson filter '$email_1_status == "verified" || $email_1_status == "catch_all_valid"' export.csv | headIf you already hold Sales Navigator profile URLs and want the email for each, use enrich instead. That route is in find an email from Sales Navigator.
Step 7: Re-run the export each month
A Sales Navigator list ages as people change jobs. The dataset here is refreshed monthly and each record carries its own fetched_at date. Re-run the export with the same filters once a month instead of editing an old 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-$(date +%Y-%m)\", \"filters\": {\"jobLevel\": [\"VP\"], \"jobFunction\": [\"Sales & Business Development\"], \"country\": [\"US\"]}, \"limit\": 5000, \"preset\": \"search\"}" \
| jq '.data | {id, status, requested}'The size from Step 2 tells you how much the market moved.
Save the export name, the filters and the date next to the CSV. Next month you diff two files, not two memories. For the surrounding workflow, see how to use Sales Navigator for lead generation and how Sales Navigator works.
What you get
Step 1 and the sizing in Step 2 ran through the free leadocean_count_leads tool on 2026-10-21. The filters were jobLevel VP, jobFunction Sales & Business Development and country US.
{"total":129494,"totalIsExact":true,"totalAll":350517,"distinctCompanies":58121,"credits":0}That is a mailable count: the tool defaults to verified, catch_all_valid and catch_all addresses. totalAll is the same filters with no email condition. The call cost 0 records.
A search row has this shape. Response shape from the API reference (placeholder values):
{
"success": true,
"data": [
{
"profile_data": {
"profile_full_name": "Jane Doe",
"profile_headline": "VP Sales at Acme",
"profile_url": "https://www.linkedin.com/in/jane-doe"
},
"contact_data": {
"has_email": true,
"has_phone": false,
"email_status": "verified",
"email_type": "work"
},
"meta": { "source_ids": { "person_id": "1234567890" } }
}
],
"meta": { "count": 1, "credits": 1, "nextCursor": "CURSOR", "depthCapped": false }
}An export CSV carries numbered headers such as email_1_address and email_1_status.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing, wrong or revoked key | Re-copy the key from app.leadocean.io. The header is x-api-key. |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency), or an export daily ceiling | Honor Retry-After. For an export ceiling, wait for resetsAt. |
| 402 | Fewer records left than the request needs | Check GET /v1/account, or move to Solo or Agency. |
| Empty results | A filter value outside the list, such as Vice President | Use VP. Check GET /v1/enums/job_level. |
| 400 on export | Over 50,000 rows in one request, or a filter the export cannot apply | Split the export into several requests, or narrow the filters. |
| 403 on export | Contact columns requested without the enrich scope | Use the search preset, or use a key with the enrich scope. |
FAQ
Can Sales Navigator export a lead list to CSV?
Not natively, per Fullenrich's guide (October 2026). LinkedIn's help center describes saving leads to lists and a 2,500-result search page, not a file download. You need a CRM sync, an extension, or a separate data source.
Does this export the same people as my Sales Navigator list?
No. It matches the same kind of people by filter. LeadOcean holds 693M people, and a filter query returns what it holds, not your saved list.
Is exporting from Sales Navigator against LinkedIn's rules?
This guide does not scrape LinkedIn. The rows come from LeadOcean's own dataset, which refreshes monthly. Check any scraping extension's terms yourself.
Does it include emails and phone numbers?
Yes with the full preset: up to 3 emails and 2 phones per row, each email with a status. Sales Navigator itself shows contact details only when the member shared them.
How much does 10,000 rows cost?
One record per row, so 10,000 rows is 10,000 records. That is ten times the Free plan's 1,000. Solo at $97 a month and Agency at $497 a month run on a fair-use pace instead of credits. See pricing.
Rebuild your Sales Navigator search and export the list
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →