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

How-to guide

How to Run the 9 Data Enrichment Jobs Every RevOps Team Needs (One API)

Size the list, find the people, fill the account, then fetch the email and phone only for the rows you keep. Nine calls, real requests, record cost on each.

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

A RevOps team needs nine enrichment jobs, and one API can run all of them. This guide gives each job as a request you can paste, with the output and what it costs in records.

The "nine tools" are nine calls against https://api.leadocean.io. You pick the ones your CRM is missing. If you want a vendor comparison first, read the best B2B data providers for RevOps teams.

TL;DR

  • Nine jobs: size, search people, search companies, list a company's people, enrich a person, enrich a company, fetch a work email, fetch a phone, export in bulk.
  • The sample run takes about 30 minutes and spends about 85 LeadOcean records. Sizing spends none.
  • The Free plan has 1,000 records, one-off, with no card. Solo is $97 a month and Agency $497, with a fair-use pace instead of credits.

Prerequisites

  • A LeadOcean API key from app.leadocean.io. Free keys get both the search and enrich scopes.
  • curl and jq. Every request sends the header x-api-key.
  • The key in your shell, never pasted into a file:
bash
export LEADOCEAN_API_KEY="paste-your-key-here"

Every example uses placeholders: Acme, acme.com, Jane Doe and +1 415 555 0133. Swap in your own accounts.

Step 1: Size the list before you spend

Sizing is the first tool because it is free. Send count=true as a query parameter with limit 1, and the response carries a total and no rows. The body is flat JSON and every filter is an array.

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 '{"title":["Revenue Operations"],"jobLevel":["Director","VP"],
       "country":["US"],"limit":1}' | jq '.meta'

meta.total is capped at 100,000. Filter values are exact strings: Director, not director. Check them with GET /v1/enums/job_level before you guess.

You can run the same count from an AI client. The hosted MCP server at https://api.leadocean.io/mcp has leadocean_count_leads, also free.

text
Use leadocean_count_leads with title ["Revenue Operations"], jobLevel ["Director","VP"],
country ["US"], facets false. Then repeat with emailStatus ["verified"].
Say what each total counted.

Step 2: Search people by filter

People search turns a filter into rows. Each person returned is 1 record. The limit is 1 to 100 a page, and you page with a cursor.

bash
curl -s "https://api.leadocean.io/v1/people/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"title":["Revenue Operations"],"jobLevel":["Director","VP"],
       "country":["US"],"limit":10}' | jq '.meta, .data[0].profile_data'

Search never returns an address or a number. It returns flags that say whether one is on file, and meta.source_ids.person_id. Keep that id: Steps 5, 7 and 8 take it. Pass meta.nextCursor back unchanged to get the next page.

Step 3: Search companies

Company search builds an account list. Each company returned is 1 record. The filters sit in the same flat body, and the same exact-string rule applies.

bash
curl -s "https://api.leadocean.io/v1/companies/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"industry":["Computer Software"],"employeeRange":["201-500"],
       "hqCountry":["US"],"limit":10}' | jq '.data[0]'

Use the domains it returns as the join key everywhere else. A domain is a safer key than a company name, and there is no lookup by name.

Step 4: List the people at an account

This call returns the people we hold at one company, one page at a time. Each person returned is 1 record. It stops at 10,000 rows per company.

bash
curl -s "https://api.leadocean.io/v1/companies/acme.com/people?limit=10" \
  -H "x-api-key: $LEADOCEAN_API_KEY" | jq '.meta'

It has no filter. To narrow by title or seniority, use Step 2 with the domain filter instead. Use this call when you want everyone at an account, such as for a coverage check on a target account.

Step 5: Enrich one person

Enrich turns one identifier into a full profile. Send exactly one of linkedin_url, email, phone or person_id. A hit is 1 record and a 404 costs nothing.

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 '{"email":"jane.doe@acme.com"}' | jq '.data.contact_data.email_status'

Set reveal_email to true when you want the address itself. It costs no extra record. This is the call to run on a CRM contact you already have, to check the email and the current role.

There is no name plus domain lookup. Search by domain first, then enrich by person_id.

Step 6: Enrich one company

Company enrich turns a domain into an account record: headcount, industry, HQ, funding and detected technologies. A hit is 1 record and a miss 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 '.data.company_data'

The response also carries company_detected_technologies and company_metrics. Use the domain as the join key back to your CRM account.

Step 7: Fetch a work email

The work email endpoint returns at most one current address for one person, or data: null. It takes a linkedin_url or a person_id. Every call is 1 record, including a call that finds nothing.

bash
curl -s "https://api.leadocean.io/v2/people/email/work?person_id=1234567" \
  -H "x-api-key: $LEADOCEAN_API_KEY"

Read status before you send. There is no refund or credit for bounced emails. Only fetch emails for people who passed your filter, because a null still spends a record.

Step 8: Fetch a phone number

The phone endpoint returns numbers best first, each with the source's own type label, such as mobile, office or unknown. It takes the same inputs as Step 7. Every call is 1 record, including a call that finds nothing.

bash
curl -s "https://api.leadocean.io/v2/people/phone?person_id=1234567" \
  -H "x-api-key: $LEADOCEAN_API_KEY"

Size phone coverage first. Search with hasPhone true and count=true gives a free total, so you know how many of your list can return a number at all.

Step 9: Export in bulk

Past a few hundred rows, stop paging and export. Bulk CSV export starts on Solo ($97 a month); it is not on Free. POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. Every row costs 1 record.

bash
curl -s -X POST https://api.leadocean.io/v1/exports \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{"name":"revops-leaders-us","preset":"search","limit":50,
       "filters":{"title":["Revenue Operations"],"jobLevel":["Director","VP"],"country":["US"]}}'

The same job runs from the Exports page in app.leadocean.io. It has a filter builder, a column picker, the record price before you start and a CSV download. Use the app when you want a file and no code.

What you get

Steps 1 and 2 spend nothing to size. These are real results from the LeadOcean MCP server on 21 October 2026 for Directors and VPs with "Revenue Operations" in the title, located in the United States. Records spent: 0.

text
leadocean_list_enum_values  name job_level
  values: C-Team, Director, Manager, Other, Staff, VP

leadocean_count_leads  title ["Revenue Operations"], jobLevel ["Director","VP"], country ["US"]
  default mailable (verified, catch_all_valid, catch_all):  2,799
  same filters, no email condition (totalAll):               4,951
leadocean_count_leads  ... plus emailStatus ["verified"]
  emailStatus verified only:                                  962

The first total is the default mailable audience. The second is filtered to verified only, an upper bound until you enrich. A search row says an email is on file. Only Step 5 or Step 7 tells you the status of the address for one person.

Step 5 returns this shape. This is the response shape from the API reference, with placeholder values, trimmed to the fields a CRM sync reads.

json
{
  "success": true,
  "data": {
    "contact_data": {
      "email_status": "verified",
      "email_type": "work",
      "contact_current_experiences": [
        { "job_title": "Head of Sales", "company_name": "Acme", "company_domain": "acme.com" }
      ]
    }
  }
}

Map email_status to a CRM field you can filter on. Treat verified, catch_all_valid and catch_all as sendable, and read the rest before any send. The job_title and company_domain fields tell you when a contact has moved on.

Step 8 returns this shape. This is the response shape from the API reference, with placeholder values, not a real person.

json
{
  "success": true,
  "data": {
    "person_id": "1234567",
    "found": true,
    "phones": [ { "phone": "+14155550133", "type": "mobile" } ],
    "best":   { "phone": "+14155550133", "type": "mobile" }
  }
}

Troubleshooting

ErrorCauseFix
401Missing, wrong or revoked keyCopy the key again from app.leadocean.io and re-export $LEADOCEAN_API_KEY.
402The Free plan's 1,000 one-off records are spentRun a shorter list, or move to Solo or Agency. Free records do not reset.
429Above your plan's rate limit per account (5 a second on Free, 50 on Solo, 200 on Agency)Slow the loop and retry after the Retry-After header.
Empty resultsA filter value outside the list, such as director for DirectorList exact strings with GET /v1/enums/job_level, then copy one.
400 on enrichTwo identifiers in one call, or noneSend exactly one of linkedin_url, email, phone or person_id.
Export refusedOver 50,000 rows in one request, or over 500,000 in a daySplit the job into requests of 50,000 rows or fewer. Wait for the daily reset.

FAQ

Which of the nine do I need first?

Start with Step 1, because it is free, then Step 5 on the contacts already in your CRM. A miss on enrich costs nothing. Add the others when a specific field is missing.

How many records does the sample run cost?

About 85. That is 10 each from Steps 2, 3 and 4, 1 each from Steps 5 to 8 and 50 from Step 9 (export needs Solo or above). Step 1 spends none. Cut the limits to 1 and the run costs about 10.

Can I look a person up by name and company?

Not directly. There is no name plus domain lookup. Search by domain first, then pass the person_id from the row to Step 5, 7 or 8.

Does a verified email guarantee no bounces?

No. Read email_status before you send, because LeadOcean gives no refund for bounces. A catch_all status means the domain accepts any address, so it cannot be confirmed.

Where do I compare vendors for these jobs?

Run all nine enrichment jobs on 1,000 free records

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

Get your free API key →