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

How-to guide

How to Build Richer Customer Profiles for an Online Store (With 8 Enrichment Calls)

Your store knows an email and an order. Eight LeadOcean calls add the person's role, employer and company, then find more buyers like them.

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

A store record is thin: an email, an order, a shipping address. This guide adds the buyer's role, employer and company profile with eight API calls, then finds more people like your best customers. It fits B2B sellers: wholesale, trade accounts, software and bulk orders.

TL;DR

  • Eight calls: size, enrich by email, read the fields, enrich the company, pull the account roster, find lookalike buyers, add a phone, export.
  • It takes about 45 minutes and spends about 60 records of the 1,000 on the free plan. Counts, a 404 and an enrichment that finds nothing cost nothing.
  • Every call is plain HTTP to https://api.leadocean.io, so a script, a store webhook or an MCP client can run it.

Prerequisites

  • A LeadOcean account on the free plan (no card). The app is at app.leadocean.io.
  • An API key exported as $LEADOCEAN_API_KEY. Free keys carry both scopes, search and enrich.
  • curl and jq.
  • A short list of customer emails from your store, for example from an order export. The examples use jane.doe@acme.com as a placeholder.
  • Consumer addresses (gmail and similar) will often return a 404. That is expected for a B2B tool.

Step 1: Size your lookalike market (free)

Count before you spend. The query below sizes the buyer role you care about. Here: purchasing titles at US retail companies of 51 to 200 people.

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 '{
    "title": ["Head of Purchasing", "Purchasing Manager", "Buyer"],
    "country": ["US"],
    "industry": ["Retail"],
    "employeeRange": ["51-200"]
  }' | jq '.meta | {total, totalIsExact, distinctCompanies}'

count=true is a query parameter, not a body field. meta.total is capped at 100,000. Enum values such as Retail are exact strings: check them with GET /v1/enums or the leadocean_list_enum_values tool.

Step 2: Enrich a customer by email

Enrich takes exactly one of linkedin_url, email, phone or person_id. There is no name plus domain lookup. A customer email is the identifier you already hold.

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", "reveal_email": true}' > jane.json

jq . jane.json

One found person costs one record. A person we hold nothing for is a 404 and costs nothing, so a loop over your whole list only spends on matches.

Step 3: Read the fields you can trust

Pull three things into your customer table: current role, email status and career history. Read them from the file you saved, so you do not spend a second record.

bash
jq '.data | {role: .contact_data.contact_current_experiences, status: .contact_data.email_status, past: .resume_data.experiences}' jane.json

The current role is in contact_data.contact_current_experiences[]. Since October 2026 resume_data holds past roles, education, certifications and awards, each when held. Past employers carry no company_id yet, so match them by name.

Step 4: Enrich the customer's company

A person profile is half the picture. Enrich the employer by domain to add size, industry and location to the account.

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'

Use the domain from the customer's work email. Group your orders by company, not by buyer, and one account with five buyers becomes one row. A company enrichment costs one record.

Step 5: Pull the roster of a top account

When one account buys often, see who else works there. GET /v1/companies/{domain}/people returns thin records, one record per person, up to 10,000 rows.

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

This is how you find the second buyer or the approver behind a repeat order. Contact points are not in the roster response. Enrich a person for those.

Step 6: Find lookalike buyers

Take the segment your best customers share and search for more of it. Keep limit small while you check the filters.

bash
curl -s -X POST "https://api.leadocean.io/v1/people/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "title": ["Head of Purchasing", "Purchasing Manager", "Buyer"],
    "country": ["US"],
    "industry": ["Retail"],
    "employeeRange": ["51-200"],
    "limit": 25
  }' | jq '.meta'

The body is flat JSON and filters are arrays. limit runs 1 to 100. Page with cursor, passing back meta.nextCursor unchanged. One search pages to 10,000 rows, then meta.depthCapped is true. Narrow the filters instead of walking the index. For the thinking behind the segment, see what an ICP is.

Step 7: Add a phone number for the accounts that matter

Phones come from GET /v2/people/phone. It costs one record per call, even when it finds nothing, so use it only on high-value accounts.

bash
curl -s -G "https://api.leadocean.io/v2/people/phone" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "person_id=PERSON_ID_FROM_SEARCH" | jq '.data'

Numbers come best first, each with a type. Filter with hasPhone=true in the search before you spend.

Step 8: Export the segment

For more than a few hundred people, stop calling one by one. POST /v1/exports takes up to 50,000 rows a request and 500,000 a day. Bulk CSV export is not on the free plan: it needs Solo ($97 a month) or higher.

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": "retail-buyers-us-51-200",
    "filters": {
      "title": ["Head of Purchasing", "Purchasing Manager", "Buyer"],
      "country": ["US"],
      "industry": ["Retail"],
      "employeeRange": ["51-200"],
      "emailStatus": ["verified"]
    },
    "limit": 2000,
    "preset": "full"
  }'

The export is async. Poll GET /v1/exports/{id}, then download from /v1/exports/{id}/download. The Exports page in the app does the same with a filter builder, a column picker, a price preview and a CSV download.

What you get

The free count from Step 1, from the leadocean_count_leads tool on 2026-10-21. It counts mailable people by default (verified, catch_all_valid or catch_all):

json
{
  "total": 942,
  "totalIsExact": true,
  "totalAll": 3759,
  "distinctCompanies": 308
}

total counts mailable people. totalAll is the same filters with no email condition. The gap is people you would pay a record for and could not email.

A person-enrich record has this shape (response shape from the API reference, placeholder values):

json
{
  "success": true,
  "data": {
    "profile_data": { },
    "contact_data": {
      "has_email": true,
      "has_phone": true,
      "email_status": "verified",
      "email_type": "work",
      "contact_emails": [{ "email": "jane.doe@acme.com", "type": "work", "status": "verified" }],
      "contact_phones": [{ "phone": "+14155550133", "type": "mobile" }]
    },
    "resume_data": { "experiences": [], "educations": [] }
  },
  "meta": { "source": "leadocean" }
}

contact_emails and contact_phones appear only with reveal_email. profile_data holds identity, headline and location; the reference leaves its fields untyped, so read your own jane.json for the names. Check email_status before you send anything. See the full profile enrichment walkthrough for every field.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerCheck $LEADOCEAN_API_KEY is exported and sent as x-api-key.
429Above the plan's rate limit (5 requests a second on Free, 200 on Agency)Honor Retry-After, or slow the loop over your customer list.
402Out of records (1,000 on Free)Upgrade, or narrow the list. Counts and 404s never spend records.
404 on enrichWe hold nothing for that email, common with consumer addressesSkip it. A 404 is free and will not change on a retry.
Empty search resultsA bad enum value, such as retail for industryUse the exact string Retail. Check GET /v1/enums.
400 export_limit_rowsMore than 50,000 rows in one exportSplit the filters into several exports.

FAQ

Which of the eight calls spend records?

Person enrich, company enrich, roster, search, phone and export. The count is free, and so is an enrichment that finds nothing. A phone call costs one record even on a miss.

Will this work for consumer stores?

Poorly. The data is professional: roles, employers, work emails. It suits B2B sellers, wholesale and trade accounts. A personal gmail address usually returns a 404.

Can I run this from an AI client instead of curl?

Yes. The hosted MCP server at https://api.leadocean.io/mcp has 13 tools, including leadocean_count_leads and leadocean_count_companies. Sign in with OAuth, no key pasted.

What does it cost at volume?

Free is 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 do I go next?

Turn the lookalike list into outreach with eight calls for a prospect list. More guides are on the blog.

Build richer customer profiles with eight calls

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

Get your free API key →