Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

Cold email data

How to Measure the State of Cold Email (in Your Own Market)

Most state-of-cold-email reports average someone else's list. Here is how to size your own pool in 15 minutes, with real queries and zero records spent.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

The state of cold email in your market is a set of numbers you can pull yourself: how many people you can mail, how clean their addresses are, and how many companies they spread across. Industry reports average other teams' lists. Your pool is the only benchmark that predicts your results.

TL;DR

  • You measure three things: the mailable pool, the email status mix, and the spread across companies.
  • It takes about 15 minutes and spends 0 LeadOcean records, because counts are free.
  • The output is a one-page baseline you can re-run monthly to see the trend in your own market.

Prerequisites

  • A LeadOcean account on the free plan. Sign up at app.leadocean.io, no card.
  • An API key exported as $LEADOCEAN_API_KEY.
  • curl and jq. Optional: the hosted MCP server at https://api.leadocean.io/mcp if you prefer to ask in plain language from Claude.

Step 1: Define one audience

Pick one audience and write it as filters. A vague audience gives a number nobody can act on.

Use the enum values exactly as the API spells them. Check them first, it is free.

bash
curl -s "https://api.leadocean.io/v1/enums" \
  -H "x-api-key: $LEADOCEAN_API_KEY" | jq 'keys'

For this guide the audience is VPs in sales and business development in the US. The filters are jobLevel "VP", jobFunction "Sales & Business Development" and country "US". Filters are arrays of strings.

Step 2: Count the mailable pool

Send the filters with count=true as a query parameter and limit=1. The body stays flat JSON. The call is free.

bash
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": ["Sales & Business Development"],
    "country": ["US"]
  }' | jq '.meta'

meta.total is capped at 100,000 on this route, so a wide audience reads as a floor. For an exact figure on a wide audience, use the free MCP tool leadocean_count_leads, which also reports distinctCompanies.

Label what you counted. The MCP tool counts only addresses with status verified, catch_all_valid or catch_all unless you say otherwise. That is a mailable count, not everyone.

Step 3: Split by email status

The status mix is the part reports hide. Count the same audience twice: once with the default mailable statuses, once with verified only.

text
leadocean_count_leads
  jobLevel: ["VP"]
  jobFunction: ["Sales & Business Development"]
  country: ["US"]
  emailStatus: ["verified"]
  facets: false

The 13 status values are verified, catch_all_valid, catch_all, risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, derived and none. Passing emailStatus replaces the default, so the count then describes only the statuses you listed.

Compare the two numbers. The gap is your catch-all exposure, the part of the list where a server accepts every address and bounces stay hidden until you send. For deliverability tactics on that gap, see the best email verifiers benchmark.

Step 4: Read the company spread

A pool of 100,000 people at 20,000 companies is a different market from 100,000 people at 90,000 companies. The first needs account-level pacing so one company does not get five emails the same week. The second does not.

The MCP count returns distinctCompanies, the number of employers the matched people span. The people-per-company ratio is your multi-thread limit. Divide total by distinctCompanies and write it down.

To size the company side, GET /v1/companies/count is free and takes the company-search filters. It returns an exact total with breakdowns by industry, headcount band, HQ country, HQ state and NAICS.

Step 5: Compare segments side by side

One pool tells you little. Three pools tell you where to aim. Re-run Step 2 and Step 3 with one filter changed each time, and keep every other filter fixed.

bash
for lvl in VP Director Manager; do
  printf "%s: " "$lvl"
  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\":[\"$lvl\"],\"jobFunction\":[\"Sales & Business Development\"],\"country\":[\"US\"]}" \
    | jq -r '.meta.total'
done

Read the three totals against the 100,000 cap. A segment that hits the cap is a floor, so switch to leadocean_count_leads for that one. Good segments to compare are job level, headcount band (employeeRange) and country. Pick the segment with a large verified share and a low people-per-company ratio. That is the cleanest place to start sending.

Step 6: Save the baseline and re-run it

Put the numbers in one row and keep it. Re-run the same query on the first of each month. The dataset is refreshed monthly, so month-over-month movement in your pool is a real trend, not noise from a changed filter.

bash
echo "$(date +%F),VP-Sales-US,$(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":["Sales & Business Development"],"country":["US"]}' \
  | jq -r '.meta.total')" >> cold-email-baseline.csv

Once the numbers look right, pull the list. Search pages up to 100 rows with cursor pagination and one search reaches 10,000 rows (meta.depthCapped marks the cap). For a larger file use POST /v1/exports, up to 50,000 rows a request and 500,000 a day. Bulk CSV export is not on the Free plan.

What you get

Output from the free leadocean_count_leads tool on 2026-10-21, audience: VP, Sales & Business Development, US.

CountFilterTotalDistinct companies
Mailable (default)verified, catch_all_valid or catch_all129,494about 58,121
Verified onlyemailStatus: verified31,14118,563
Everyone, no email conditionnone350,517not returned

Two readings. Only about a quarter of the mailable pool (31,141 of 129,494) is verified today. The rest is catch-all, which is where send-time risk sits.

The search call returns this response shape from the API reference, with placeholder values:

json
{
  "success": true,
  "data": [],
  "meta": {
    "total": 100000,
    "totalIsExact": false,
    "distinctCompanies": 58121,
    "countOnly": true,
    "credits": 0
  }
}

data is empty and meta.countOnly is true because you asked for a count. totalIsExact: false means the total is a floor. Nothing was spent.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerRe-copy the key from app.leadocean.io and export $LEADOCEAN_API_KEY
429Above the plan's rate limit (5 requests a second on Free, 200 on Agency)Honour the Retry-After header and space the calls
402The 1,000 free records are spentCounts stay free. Moving to a paid plan restores record-returning calls
Empty or zero resultsA bad enum value, such as "VP of Sales" for jobLevelList valid values with GET /v1/enums or leadocean_list_enum_values
meta.total stuck at 100,000The count cap on the search routeNarrow the filters, or use leadocean_count_leads for an exact figure
Export refusedOver 50,000 rows a request or 500,000 a daySplit the audience into smaller exports

FAQ

Why not just use a published cold email benchmark?

Published figures average many senders, lists and offers. Your pool size and status mix are measurable and specific. Use reports for context, and your baseline for decisions.

Does counting spend records?

No. Counts, enum lookups and count=true with limit=1 are free. A record is a person or company you receive, so a count never costs one.

Is a count the same as a mailable list?

Only if you label it that way. A count with hasEmail or hasPhone is not a mailable count. The default MCP count is mailable (verified, catch_all_valid or catch_all). Say which one you quote.

How often should I re-run it?

Monthly. The dataset refreshes monthly and each record carries its own fetched_at date.

Where do warm-up and sequencing fit?

After the list. Pool size tells you how many domains and mailboxes you need. See cold email warm-up tools and cold email campaign tools. Plans are on pricing. More guides are in the blog.

Measure your own cold email market before you send a single email.

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →