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

How-to guide

How to Audit B2B Data Quality (Before You Send or Buy)

Data quality is four numbers you can measure in an hour. Here are the queries, the output and the thresholds.

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

B2B data quality is four measurable things: fit, reachability, freshness and duplication. Most guides stop at "verify your data". This one gives the queries, so you can score any list or any provider in under an hour.

TL;DR

  • Score a segment on four numbers: how many records match, how many have a sendable email, how old the verification is, and how many are duplicates.
  • Takes 30 to 45 minutes. Counts are free. One sample page of 25 people and two enrichments spend about 27 records, out of the 1,000 on the Free plan.
  • Send only to verified and catch_all_valid first. Treat risky, unknown and untested as a separate, smaller test batch.

Prerequisites

  • A LeadOcean account. The Free plan is enough: 1,000 records for life, no card, 5 requests a second.
  • An API key in your shell: export LEADOCEAN_API_KEY=...
  • curl and jq. Optional: the hosted MCP server at https://api.leadocean.io/mcp, which uses OAuth sign-in and needs no key.
  • A segment in mind. Example here: VPs in the United States.

Step 1: Define fit and size it for free

Fit is whether the people in the list match your buyer. Size the segment first, because every later number is a share of it.

Use the free count. In the REST API, send count=true as a query parameter and limit: 1 in the body. Over MCP, call leadocean_count_leads.

bash
curl -s "https://api.leadocean.io/v1/people/search?count=true" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"jobLevel":["VP"],"country":["US"],"limit":1}' | jq '.meta | {total, totalIsExact, distinctCompanies}'

Filter values are exact strings. Check them with leadocean_list_enum_values or GET /v1/enums/job_level before you trust an empty result.

Step 2: Measure reachability by email status

Reachability is the share of the segment you can email without bouncing. Count the segment twice: once with LeadOcean's default mailable set, once with verified only.

The default counts verified, catch_all_valid and catch_all. Passing emailStatus replaces that default, and passing every value returns the unfiltered total.

bash
echo "mailable default: verified, catch_all_valid, catch_all"
curl -s "https://api.leadocean.io/v1/people/search?count=true" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"jobLevel":["VP"],"country":["US"],"limit":1}' | jq '.meta.total'

echo "verified only"
curl -s "https://api.leadocean.io/v1/people/search?count=true" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"jobLevel":["VP"],"country":["US"],"emailStatus":["verified"],"limit":1}' | jq '.meta.total'

A count with emailStatus is not a mailable count of the whole list. Label it by what you filtered. The 13 status values are in GET /v1/enums/email_status.

Step 3: Check freshness on a sample

Freshness is how recently the record and its email were checked. Pull one page of 25, then enrich two of the rows with reveal_email to read the dates.

bash
curl -s "https://api.leadocean.io/v1/people/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"jobLevel":["VP"],"country":["US"],"emailStatus":["verified"],"limit":25}' \
  | jq '.meta.nextCursor, (.data | length)'

The dataset is refreshed monthly, and each record carries its own fetched_at date. On an enriched email, verified_batch_date is the date of the verification run. A null there means LeadOcean did not run the check itself. Ask any provider the same question.

For a person who changed jobs, enrich returns career history (resume_data) so you can see whether the current role matches the title you searched.

Step 4: Test duplication and concentration

Duplication is how many rows point at the same person or the same company. The people count carries meta.distinctCompanies, the number of employers the matched people span.

bash
curl -s "https://api.leadocean.io/v1/people/search?count=true" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"jobLevel":["VP"],"country":["US"],"limit":1}' \
  | jq '.meta | {people: .total, employers: .distinctCompanies, per_employer: (.total / .distinctCompanies)}'

If one employer holds dozens of matches, you are buying a few accounts many times. Size the company side for free with GET /v1/companies/count, or the MCP tool leadocean_count_companies. Then pull by account, not by title.

Step 5: Spot-check records and set your gate

A spot check is 25 real rows, read by a human. Look for title drift, wrong countries and role mailboxes. Then write down a gate.

text
Send gate (example, tune to your tolerance)
- email_status in (verified, catch_all_valid)      -> send
- email_status in (catch_all, risky)               -> small test batch, watch bounces
- email_status in (unknown, untested)              -> do not send
- email_status in (invalid, role, disposable,
  spam_trap, abuse)                                -> drop

LeadOcean gives no refund or credit-back for bounced emails, so the gate is yours to enforce. Read email_status before every send.

What you get

Free counts from leadocean_count_leads, run on 2026-10-21 for jobLevel VP, country US:

json
{
  "default_mailable": { "total": 1242801, "totalIsExact": true, "totalAll": 3102417, "distinctCompanies": 226527 },
  "verified_only":    { "total": 257840,  "totalIsExact": true, "distinctCompanies": 83722 }
}

Read it like this: of 3,102,417 US VPs, 1,242,801 are in the default mailable set (about 40%), and 257,840 are verified (about 8%). The first number is the list you could mail. The second is the list you can trust most. Both cost 0 records.

An enriched record carries the dates. Response shape from the API reference (placeholder values):

json
{
  "success": true,
  "data": {
    "contact_data": {
      "has_email": true,
      "email_status": "verified",
      "contact_emails": [
        { "email": "jane.doe@acme.com", "type": "work", "status": "verified", "verified_batch_date": "2026-09-20" }
      ]
    }
  },
  "meta": { "source": "leadocean" }
}

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-keyRe-export $LEADOCEAN_API_KEY and resend
429Above the plan's rate limit (5 a second on Free, 200 on Agency)Honor Retry-After, or batch the sizing calls
402Out of records (Free is 1,000 for life)Counts stay free. Move to Solo at $97 a month for more
Empty resultsBad enum value, such as vp for jobLevelUse exact strings from GET /v1/enums: VP for jobLevel, vp for seniority
meta.total stops at 100,000The count capNarrow the filters until the total is exact
meta.depthCapped is trueOne search pages to 10,000 rowsSplit into smaller searches by country or industry

FAQ

What is a good email verification rate?

Set it by status, not by a single percent. Send to verified and catch_all_valid first, test catch_all and risky in small batches, and drop the rest. LeadOcean publishes no bounce guarantee, so your own bounce rate on the first 200 sends is the real test.

How often should I re-check B2B data?

Re-check before every large send and at least monthly. LeadOcean's dataset is refreshed monthly, and each record carries its own fetched_at date. Compare it with the date of your send.

Does a catch-all domain mean the email is bad?

No. A catch-all server accepts any address, so the verifier cannot confirm the mailbox. catch_all_valid is a stronger signal than catch_all. Treat both as a test batch.

Can I run this audit over MCP instead of curl?

Yes. leadocean_count_leads, leadocean_list_filters and leadocean_list_enum_values are free. Ask your assistant to count the same segment with and without emailStatus: verified. See pricing for plan limits and the data validation techniques guide for the wider checklist.

What does tech data quality look like?

The same four checks apply to technographic data: coverage, freshness, duplicates and fit. See our Wappalyzer review for how one tech-detection source scores. For background, start with what B2B data is.

Score your own list before you spend a record

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

Get your free API key →