TL;DR
- A VP of Marketing's email comes from a data source, a pattern you test, or the person themselves. A data source with a status label is the fastest.
- It takes about 10 minutes and about 6 LeadOcean records for one company. Sizing the audience is free.
- Read
email_statusbefore you send. Skip anything that is notverified,catch_all_validorcatch_all.
Prerequisites
- A LeadOcean account and API key from app.leadocean.io. The free plan has no card and 1,000 records, one-off.
- The key in your shell as
$LEADOCEAN_API_KEY. The key needs the search and enrich scopes. Free keys get both. curlandjq. The free counts also run from any MCP client connected tohttps://api.leadocean.io/mcp.
export LEADOCEAN_API_KEY="paste-your-key-here"Step 1: Size the audience by region for free
Count before you pull. A VP of Marketing is a job level (VP) in a job function (Advertising & Marketing). Filter on those two, not on a title string, so "VP, Growth Marketing" and "Vice President of Brand" are both in.
Use leadocean_count_leads with jobLevel ["VP"], jobFunction ["Advertising & Marketing"],
salesRegion ["EMEA"], facets false. Report the total and say which email statuses it
counted. Do not call any tool that spends records.The same count over REST is a search with count=true and limit=1 as query parameters. It returns meta.total and no rows.
curl -s "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": ["Advertising & Marketing"],
"salesRegion": ["EMEA"],
"emailStatus": ["verified", "catch_all_valid", "catch_all"]
}' | jq '.meta'On 21 October 2026 the MCP counts for mailable VPs in marketing were:
Region (salesRegion) | Mailable VPs of Marketing |
|---|---|
| NORAM | 51,435 |
| EMEA | 4,921 |
| APAC | 4,119 |
| LATAM | 459 |
| All regions | 78,666 |
"Mailable" here means the tool's default email statuses: verified, catch_all_valid and catch_all. The four regions add up to 60,934. The rest have no region on file. Narrowing to verified alone gave 15,553 worldwide on the same date. Without any email filter the level and function match 235,953 people, so about one in three has an address worth sending to.
Step 2: List the VPs of Marketing at one company
Search by company domain. This returns a thin roster: name, headline, current role and company. It never returns addresses. Each person returned counts one record, so keep limit low.
curl -s https://api.leadocean.io/v1/people/search \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
-d '{
"domain": ["acme.com"],
"jobLevel": ["VP"],
"jobFunction": ["Advertising & Marketing"],
"limit": 5
}' | jq '.data[] | {headline: .profile_data.headline, id: .meta.source_ids.person_id, status: .contact_data.email_status}'Each row carries has_email, email_status and email_type as flags. That tells you whether an address exists and how good it is before you ask for it. If a company has no VP, widen to jobLevel ["VP","Director"] and read the roster again.
Step 3: Reveal the work email
Send the person_id from the roster to the enrich endpoint with reveal_email set to true. It costs one record and returns every email and phone we hold for that person at no extra charge.
curl -s https://api.leadocean.io/v1/people/enrich \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
-d '{ "person_id": "123456789", "reveal_email": true }' \
| jq '.data.contact_data | {email_status, email_type, contact_emails}'You can also ask for one work address only. GET /v2/people/email/work takes the same id as contact_id and returns one current-employer address that was checked, or data: null. It costs one record per call, including a call that finds nothing.
curl -s "https://api.leadocean.io/v2/people/email/work?contact_id=123456789" \
-H "x-api-key: $LEADOCEAN_API_KEY" | jq '.data'Step 4: Read the email status before you send
The status is the verification result, not a guess. Use the table to decide what goes into a sequence.
email_status | What it means | Send? |
|---|---|---|
verified | The mailbox was checked and exists | Yes |
catch_all_valid | The domain accepts everything, and we confirmed this mailbox | Yes |
catch_all | The domain accepts everything, so a pass proves nothing | Yes, at lower volume |
risky, unknown, untested | Not confirmed | No |
invalid, role, disposable, spam_trap, abuse | Bad or shared address | Never |
An address of type work_other belongs to a former employer. The /v2/people/email/work endpoint never returns one. Check email_type is work before you treat the address as current.
Step 5: Test patterns only when the data has nothing
Use patterns last. Most companies use one format, and the VP of Marketing follows it. Pull any address you hold at that domain, copy its format, and apply it to the name you need.
jane.doe@acme.com first.last
jdoe@acme.com first initial + last
jane@acme.com first
janed@acme.com first + last initial
jane_doe@acme.com first_lastA pattern is a guess. Never send to a guessed address without a check. Run each one through an email verifier of your own, and treat a catch-all domain as unproven, because it accepts any address you try.
Send a small first batch, watch bounces, and drop the pattern if bounces climb. LeadOcean gives no refund or credit-back for bounced emails, so read email_status first.
What you get
Step 1 gave real numbers from a free count on 21 October 2026. Step 3 returns the person and their contact block. This is the response shape from the API reference, with placeholder values.
{
"data": {
"profile_data": { "headline": "<headline>" },
"contact_data": {
"has_email": true,
"has_phone": true,
"email_status": "verified",
"email_type": "work",
"contact_emails": [
{ "email": "jane.doe@acme.com", "type": "work", "status": "verified", "verified_batch_date": "2026-09-20" }
],
"contact_phones": [
{ "phone": "+14155550133", "type": "mobile", "priority": 1 }
]
},
"meta": {}
}
}verified_batch_date is the date of the verification run. A null date means the check was not run by LeadOcean, and does not mean the address is unverified. Each record also carries its own fetched_at date, and the dataset refreshes monthly.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing, wrong or revoked key | Re-copy the key from app.leadocean.io and export $LEADOCEAN_API_KEY again. |
| 429 | Over your plan's rate on one key (5 a second on Free, 50 on Solo, 200 on Agency), or a paid plan's fair-use window is reached | Wait the Retry-After seconds. Send full pages of 100 rather than more calls. |
| 402 | Free plan: the 1,000 records are spent | Check GET /v1/account, then move to Solo ($97 a month) or Agency ($497 a month). Free records do not reset. |
| 400 or a count of 0 | A filter value outside the catalogue, such as jobFunction: "Marketing" | Resolve it with leadocean_list_enum_values or GET /v1/enums/job_function and pass the exact string. |
| 404 on enrich | We hold nothing to enrich that person by | It costs nothing. Try the next person on the roster. |
| 400 on a large export | limit is above 50,000 rows for one export | Split by salesRegion or country and run several exports. |
FAQ
How do I find a VP of Marketing's email for free?
Size the audience with the free count tools, then spend part of the 1,000 free records on one company. The free plan has no card and records are one-off. Counting never spends a record.
What email format do VPs of Marketing use?
The same format as the rest of the company. Common ones are first.last, first initial plus last, and first alone. Copy a known address at that domain, and verify any guess before you send.
Is a catch-all address safe to send to?
It is riskier. A catch-all domain accepts any address, so a pass proves nothing. LeadOcean marks catch_all_valid when the mailbox was confirmed. Send catch_all in small batches.
Can I pull hundreds of VPs of Marketing at once?
Yes, on a paid plan. Bulk CSV export is included on Solo and Agency, not on Free. Use an export with the Step 1 filters. An export takes up to 50,000 rows a request and 500,000 a day, one record per row. The app's Exports page does the same from a filter builder.
Does the record show where they worked before?
Yes. Since October 2026, person enrich returns resume_data: past roles with title, company name and start and end dates, plus education and certifications, each when held. Past employers carry no company_id yet. The current role sits in contact_current_experiences.
How fresh is the data?
The dataset is refreshed monthly. Each record also carries its own fetched_at date, so check it before you send to anyone who may have changed jobs. An old fetched_at date is a reason to re-check the person before you write.
Why does a VP of Marketing email bounce?
Usually the address was guessed, the person left, or the domain is catch-all and the mailbox never existed. Read email_status, email_type and the fetched_at date before you send. Bounced emails are not refunded.
Where do I go for other roles?
Same recipe, different filters. See how to find a marketing director's email, a VP of Sales and a VP of Engineering. Plans are on pricing.
More recipes live in the blog hub.
Find your VP of Marketing's email free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →