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

Data quality how-to

How to Overcome Firmographic Data Accuracy Challenges (With the LeadOcean API)

Five checks you can run in an afternoon, with the queries and the output. Most of them cost zero records.

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

TL;DR

  • Firmographic errors come from four places: estimated fields, missing values, loose industry labels and stale records. Each has a check you can script.
  • The whole run takes 30 to 45 minutes and spends about 10 records. The sizing steps are free.
  • The rule that fixes most of it: filter on brackets and labels you have verified, then sample-check before you commit a list.

Prerequisites

  • A LeadOcean account. The Free plan gives 1,000 records for life, no card.
  • An API key in your shell as $LEADOCEAN_API_KEY.
  • curl and jq.
  • Optional: the LeadOcean MCP server at https://api.leadocean.io/mcp, to run the free count tools from an agent.

Step 1: Size the segment before you trust it

Start with a free count. It shows how big the segment is and how the data splits, and it spends nothing.

bash
curl -s -G "https://api.leadocean.io/v1/companies/count" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "industry=Software Development" \
  --data-urlencode "hqCountry=US" \
  --data-urlencode "employeeRange=51-200" | jq '.data.total'

The response also carries breakdowns by HQ state and NAICS code. Read them. A segment packed into one state is a different market from one spread evenly. A long tail of odd NAICS codes tells you the industry label is loose (Step 3).

Step 2: Filter on brackets, not exact numbers

Total headcount is also a blunt field. A 400-person company can be mostly engineers or mostly support, and the number does not say which. Pair the size bracket with a people filter such as jobFunction when the mix matters to your offer.

Exact headcount is the field teams over-trust. Use employeeRange for sizing, and use minEmployees and maxEmployees only when you need a cut inside a bracket.

The two filters do not match the same companies. minEmployees and maxEmployees return only records that hold an exact figure. A company with a bracket but no exact count is dropped.

Run both and compare:

bash
curl -s -G "https://api.leadocean.io/v1/companies/count" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "industry=Software Development" \
  --data-urlencode "hqCountry=US" \
  --data-urlencode "employeeRange=51-200" | jq '.data.total'

curl -s -G "https://api.leadocean.io/v1/companies/count" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "industry=Software Development" \
  --data-urlencode "hqCountry=US" \
  --data-urlencode "minEmployees=51" \
  --data-urlencode "maxEmployees=200" | jq '.data.total'

The gap is the number of companies your exact-number filter silently hides. The same rule applies to minRevenue and minFounded: the filter only matches records where we hold the value.

Step 3: Check the industry label against its neighbours

Industry labels overlap. Resolve the enum before you filter, then decide which neighbours belong in your segment.

bash
curl -s "https://api.leadocean.io/v1/enums/industry?q=software" \
  -H "x-api-key: $LEADOCEAN_API_KEY" | jq '.data.values'

Filter values are exact strings. A wrong value returns an empty result, not an error (see Troubleshooting).

To go finer than a label, add keywords, which matches the company description, specialties and tags. Use excludeKeywords to drop false fits.

bash
curl -s -X POST "https://api.leadocean.io/v1/companies/search?count=true" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "industry": ["Software Development"],
    "hqCountry": ["US"],
    "employeeRange": ["51-200"],
    "keywords": ["payments"],
    "limit": 1
  }'

count=true is a query parameter and the call spends no records. That is how you test a narrower definition of your segment before you pull a row.

Step 4: Sample-check a few records against your own data

Never validate a field by trusting it. Pull a small sample and compare it with what you know. Ten records is enough to see a pattern.

bash
curl -s -X POST "https://api.leadocean.io/v1/companies/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "industry": ["Software Development"],
    "hqCountry": ["US"],
    "employeeRange": ["51-200"],
    "limit": 10
  }' > sample.json

For accounts already in your CRM, enrich by domain and diff the fields. A company that is not in the data returns a 404 and costs nothing.

bash
curl -s -X POST "https://api.leadocean.io/v1/companies/enrich" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "acme.com"}' | jq '{name: .data.company_data.company_name, fetched_at: .data.meta.fetched_at}'

Score the sample by field and write the result down.

FieldWrong in sampleWhat to do
HQ country0 of 10Safe to filter on
Headcount3 of 10Filter on the bracket only
Private revenueEstimatedUse as a band, never a gate

The numbers in that table are an example of how to log your own run, not a LeadOcean result. If headcount is wrong on 3 of 10 and HQ country on 0 of 10, trust country and treat headcount as a bracket. Private companies do not publish revenue, so treat that field as a rough band and never as a hard gate.

Two habits make this step worth the ten records. First, sample the same segment again after each refresh, so you see drift and not a one-off result. Second, keep the sample file with a date in its name. When a rep says a list was wrong, you can check what the data said on the day you pulled it.

Step 5: Re-enrich on a schedule

Records age. The dataset is refreshed monthly and each record carries its own fetched_at date. Use that date to decide what to refresh.

bash
jq -r '.[] | select(.last_enriched < "2026-07-23") | .domain' crm_export.json |
while read d; do
  curl -s -X POST "https://api.leadocean.io/v1/companies/enrich" \
    -H "x-api-key: $LEADOCEAN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"domain\": \"$d\"}"
  sleep 0.25
done

The sleep keeps you under 5 requests a second on Free. On Agency the limit is 200 a second. For a full list refresh, POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. The Exports page in the app (app.leadocean.io) shows the record price before you download. Bulk CSV export is not on Free.

What you get

On 2026-10-21 the free leadocean_count_companies tool returned these totals for US companies in Software Development.

FilterCompanies
employeeRange 51-2009,261
minEmployees 51, maxEmployees 2006,395
Gap2,866

The NAICS breakdown on the bracket count shows how loose the label is. The top code, 541511, covers 5,890 of the 9,261. The rest spread over more than 15 other codes, down to single digits per code.

The free enum lookup for "software" on the same date returned seven industry values. They were Computer Software, Data Security Software Products, Desktop Computing Software Products, Embedded Software Products, IT System Custom Software Development, Mobile Computing Software Products and Software Development. Filtering on one label leaves the other six out.

A company enrich response has this shape (response shape from the API reference, placeholder values, fields abridged):

json
{
  "success": true,
  "data": {
    "company_data": {
      "company_name": "Acme",
      "company_domain": "acme.com"
    },
    "company_metrics": {},
    "meta": { "fetched_at": "2026-10-01", "schema": "leadocean.company.v1" }
  },
  "meta": { "credits": 1 }
}

Run Step 1 again after every refresh. If the segment total moves by a large amount in a month, find out why before you launch a campaign on it. A big move usually means the label, a bracket or a country changed, not that the market did.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerSend the key as x-api-key: $LEADOCEAN_API_KEY. Check it in the app under API keys.
429Above the plan's rate limit (5 a second on Free, 200 on Agency)Wait for Retry-After, or add a sleep between calls.
402Out of records on the Free planThe 1,000 records are spent. Move to a paid plan, see pricing.
200 with no rowsA wrong enum value, such as "Software" instead of "Software Development"Resolve the value with GET /v1/enums/industry. Values are exact strings.
404 on enrichThe company is not in the dataNothing is charged. Try the linkedin_url instead of the domain.
Export refusedOver 50,000 rows a request or 500,000 a daySplit the pull across requests and days.

FAQ

Which firmographic fields are least accurate?

Private-company revenue and funding stage. Private firms do not publish revenue, and funding changes with each round. Treat both as bands and check a sample before you filter on them.

How often should I refresh firmographic data?

Monthly is a sensible default for active pipeline, since the LeadOcean dataset itself is refreshed monthly. Refresh older records first, using each record's fetched_at date.

Why does my count change when I switch from a bracket to exact numbers?

Exact bounds match only records that hold an exact figure. Brackets also match records that hold only the band. Step 2 shows the gap on a real segment.

Should I fix bad fields in my CRM or filter them out?

Do both, in that order. Overwrite fields you have verified, such as HQ country. Filter out fields you cannot verify, such as revenue, so they stop deciding who gets a rep's time.

Does checking accuracy cost records?

Counts and enum lookups cost nothing, and an enrichment that finds nothing costs nothing. The sample in Step 4 spends one record per company returned.

Can I verify a field against a second source?

Yes, and for revenue you should. Pull the same domain from a second provider and compare. If the two disagree by a wide margin, drop the revenue gate from your scoring.

Related reading: best firmographic data providers, what firmographic data is, providers ranked for B2B sales teams, and the blog hub. Plans are on the pricing page.

Check your firmographic data against a free, sizeable segment

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

Get your free API key →