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

How-to guide

How to Test Why Your Legacy Data Provider Is Failing (With 45 Records)

Legacy providers fail in three measurable ways. Here is a 45-record test you can run against your own CRM sample in under an hour.

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

Legacy data providers fail in three ways you can measure: the record is old, the email status is hidden, and the contract hides what you actually pay for. This guide tests the first two against your own CRM, with real requests.

The root cause is decay. B2B contact data goes wrong as people change jobs, and a database refreshed on a slow cycle carries those errors until the next refresh. A provider also tends to sell you an email with one confidence label, so you cannot tell a verified address from a guess.

Three things follow. You pay for records that are already wrong. You cannot filter on email quality. And the pricing makes testing hard, because you commit before you can check.

LeadOcean refreshes its dataset monthly and each record carries its own fetched_at date, so you can see the age of every row you pay for. That is the property the test below checks.

TL;DR

  • You will take a sample of contacts from your CRM and compare them to a fresh source. It takes 45 to 60 minutes.
  • The test spends about 45 LeadOcean records: 25 for a people pull and 20 for enrichment. Sizing calls cost nothing. The Free plan has 1,000 records for life, so you stay inside it.
  • You end with three numbers: how many contacts changed jobs, how many emails have a bad status, and how many replacement contacts exist for your target list.

Prerequisites

  • A LeadOcean key from the Free plan, no card needed. Export it as $LEADOCEAN_API_KEY.
  • A CSV of 20 contacts from your CRM that you currently pay a legacy vendor for. You need the LinkedIn URL, email, company domain and title.
  • curl and jq. Free plan limit is 5 requests a second, so keep scripts sequential.

Step 1: Pull current people for one of your accounts

Pick one company from your CRM and list who works there today. This costs 1 record per person returned, so cap it at 25.

bash
curl -s "https://api.leadocean.io/v1/companies/acme.com/people?limit=25" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  | jq '.data[] | {name: .profile_data.profile_full_name,
      title: .contact_data.contact_current_experiences[0].job_title,
      email_status: .contact_data.email_status, fetched_at: .meta.fetched_at}'

Compare the list to your CRM for the same account. Count the people in your CRM who no longer appear, and the people here you do not have. Write both numbers down.

Step 2: Re-check 20 CRM contacts by LinkedIn URL

Enrich each contact and compare the current role to the title in your CRM. An enrichment that finds nothing returns a 404 and costs nothing. One lookup takes exactly one of linkedin_url, email, phone or person_id.

bash
while IFS=, read -r linkedin_url crm_title; do
  curl -s -X POST https://api.leadocean.io/v1/people/enrich \
    -H "x-api-key: $LEADOCEAN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"linkedin_url\": \"$linkedin_url\", \"reveal_email\": true}" \
  | jq -r --arg crm "$crm_title" \
    '[.data.contact_data.contact_current_experiences[0].job_title, $crm] | @tsv'
  sleep 0.3
done < contacts.csv

Since October 2026 the same response also carries resume_data, which lists past roles. That tells you when someone moved, not only that they did. Count the rows where the two titles or companies differ.

Step 3: Check email status, not just email presence

A legacy export gives you an address. A useful source gives you a status. LeadOcean returns one of 13 email_status values: verified, catch_all_valid, catch_all, risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, derived and none.

Step 2 already sets reveal_email, so read the status from the same responses instead of paying twice. For one contact it looks like this:

bash
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/jane-doe-example", "reveal_email": true}' \
  | jq '.data.contact_data | {contact_emails, email_status}'

Reveal costs no extra record. Then compare against what your legacy vendor sold you. If its export has no status column, that is the finding. LeadOcean does not refund or credit bounces, so read email_status before sending.

Step 4: Size the replacement list for free

Finally, count how many contacts match your target profile today. Send count=true as a query parameter with limit=1. The body is flat JSON and filters are arrays.

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

The same count works from an MCP client with leadocean_count_leads. Enum values are exact strings, so check them with leadocean_list_enum_values before you guess. Counts do not spend records.

What you get

I ran the Step 4 filters through leadocean_count_leads on 21 October 2026.

FilterTotalCompanies
VP, Sales & Business Development, US, 201-500 employees, no email filter35,380not returned
Same, default mailable (verified, catch_all_valid or catch_all)12,2816,321
Same, emailStatus: verified only3,4872,168

The gap between 35,380 and 3,487 is the point. A third of the audience is mailable by the default rule, and under 10 percent is verified. A source that does not show you this split sells the 35,380 as one number.

For a record-level call, this is the response shape from the API reference for the Step 1 roster (placeholder values). Rows are thin: no contact points until you enrich.

json
{
  "success": true,
  "data": [
    {
      "profile_data": {
        "profile_full_name": "Jane Doe",
        "profile_headline": "VP Sales at Acme"
      },
      "contact_data": {
        "has_email": true,
        "email_status": "verified",
        "email_type": "work",
        "contact_current_experiences": [
          { "job_title": "VP Sales", "company_name": "Acme", "company_domain": "acme.com" }
        ]
      },
      "meta": { "source_ids": { "person_id": "1234567" }, "fetched_at": "2026-10-01" }
    }
  ],
  "meta": { "count": 1, "limit": 25, "credits": 1, "nextCursor": null }
}

Your own test gives you the three numbers from the TL;DR. If more than a few of your 20 contacts changed jobs, or your vendor export has no status column, you have found the failure.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-keyCheck $LEADOCEAN_API_KEY is exported in this shell
429More than 5 requests a second on Free (200 on Agency)Keep the sleep 0.3 and read the Retry-After header
402The 1,000 Free records are spentCheck GET /v1/usage, then move to Solo at $97 a month
404 on enrichNobody matched that inputNo record is spent. Try the email or person_id instead
Empty search resultsEnum value is not an exact string, such as vp instead of VPLook it up with GET /v1/enums or leadocean_list_enum_values
Roster stops earlymeta.depthCapped true: one walk pages to 10,000 rowsNarrow by title or level instead of paging further

FAQ

Do legacy providers all fail the same way?

No. Some are fine on coverage and weak on status. Some price by contract term, which makes testing before buying hard. Run the test on your sample rather than trusting a category.

How many contacts should I test?

Twenty is enough to see a pattern. If you want a tighter figure, repeat Step 2 on 50. Each enrichment that returns data costs one record.

Does LeadOcean replace my CRM or sequencer?

No. It is a data API with a hosted MCP server. It has no dialer, sequencer, CRM or Chrome extension. You pull records and send them to the tools you already use.

What does it cost after the test?

Free is $0 for 1,000 records for life. Solo is $97 a month and Agency is $497 a month, with a fair-use pace instead of credits. See pricing.

Where can I read more on data quality?

Test your current provider against fresh data in under an hour

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

Get your free API key →