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

How-to guide

How to build a B2B lead list for ecommerce brands (US retail, 51 to 1,000 employees)

Name the buying committee, size it with a free count, pull each role through the API, and write one angle per role.

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

You sell to online stores. This guide gets you a sized, role-by-role list of their decision makers, with a free count first and about 350 records spent on a sample.

TL;DR

  • Time: 30 to 45 minutes from blank page to a sample list with emails.
  • Cost: the counts are free. A 300-person sample plus 50 enrichments spends about 350 of the 1,000 records on the Free plan.
  • Result: three role lists (growth, operations, finance), each with its own message angle.

Prerequisites

  • A LeadOcean account and key. The Free plan is $0, has no card, and gives 1,000 records for life. Sign up at app.leadocean.io/register.
  • The key in your shell: export LEADOCEAN_API_KEY=your_key_here.
  • curl and jq. Any HTTP client works the same way.
  • Optional: the LeadOcean MCP server in Claude, if you want to run the counts in chat. It has 13 tools and signs in with OAuth.
  • One sentence on what you sell. The role map in Step 1 depends on it.

Step 1: Map the buying committee

An ecommerce brand buys through three groups, and the title that signs depends on what you sell. Pick the primary owner first, then add the two who can block or fund the deal.

Role groupTypical titlesjobFunctionjobLevelCares about
GrowthHead of Ecommerce, VP Marketing, Director of GrowthAdvertising & MarketingVP, DirectorConversion, CAC, repeat rate
OperationsVP Operations, Director of FulfillmentOperations, Supply Chain & LogisticsVP, DirectorShip time, returns, cost per order
Finance and execCFO, COO, founderFinance & Accounting, General Business & ManagementC-TeamMargin, payback, risk

Small stores have no VP layer. At 50 to 200 people the founder or the head of ecommerce usually signs. At 500 or more, expect all three groups and a longer cycle.

Rank the groups by who feels the pain you fix. A returns tool starts with operations. A conversion tool starts with growth. A payments or lending product starts with the exec group. Start with one group, not all three, and add the others once the first list has replies.

Write the committee down as a config so every later call reads from one place.

json
{
  "market": "US retail and ecommerce brands",
  "company_size": ["51-200", "201-500", "501-1000"],
  "groups": {
    "growth": { "jobFunction": ["Advertising & Marketing"], "jobLevel": ["VP", "Director"] },
    "operations": { "jobFunction": ["Operations", "Supply Chain & Logistics"], "jobLevel": ["VP", "Director"] },
    "exec": { "jobLevel": ["C-Team"] }
  }
}

Step 2: Find the right industry values

There is no single "ecommerce" industry value. The industry filter holds 534 exact strings, and online sellers sit under several retail labels. Look them up instead of guessing, because a wrong string returns an empty result.

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

In Claude with the MCP server, the same lookup is free:

text
Use leadocean_list_enum_values with name "industry" and q "retail". List the values.

On 2026-10-21 this returned 21 retail values. Five matter here: Retail, Online and Mail Order Retail, Retail Apparel and Fashion, Retail Health and Personal Care Products and Retail Furniture and Home Furnishings.

One honest caveat. Online and Mail Order Retail is a thin label: in the US count below it held 68 of the mailable VP and C-level people, against 18,836 under plain Retail. If you only filter on the online label you miss most pure-play stores. Use the retail family, then cut by headcount and by the role groups.

Step 3: Size the list with a free count

Count before you spend a record. A count costs nothing, and it tells you whether the market is 300 people or 30,000.

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 '{
    "industry": ["Retail", "Online and Mail Order Retail", "Retail Apparel and Fashion",
                 "Retail Health and Personal Care Products", "Retail Furniture and Home Furnishings"],
    "country": ["US"],
    "employeeRange": ["51-200", "201-500", "501-1000"],
    "jobLevel": ["VP", "C-Team"]
  }' | jq '.meta'

The count=true flag goes in the query string, not the body. The data array comes back empty and meta.total holds the number. It is capped at 100,000.

Run one count per role group. In chat, the MCP tool leadocean_count_leads takes the same filters and also reports distinctCompanies.

text
Use leadocean_count_leads with industry ["Retail","Online and Mail Order Retail","Retail Apparel and Fashion","Retail Health and Personal Care Products","Retail Furniture and Home Furnishings"], country ["US"], employeeRange ["51-200","201-500","501-1000"], jobLevel ["VP","Director"], jobFunction ["Advertising & Marketing"].

Read the result as a range, not a promise. Companies with no VP layer drop out of the VP and Director groups, and that is correct. They belong in the exec group, where the founder is the buyer.

Two points on reading the result. The default count includes only addresses worth sending to: verified, catch_all_valid or catch_all. And the count does not tell you how many of those people have a phone, so do not read it as a call list.

Step 4: Pull one list per role group

Search each group separately so you can tag them and write to them differently. The body is flat JSON, filters are arrays, and limit runs from 1 to 100. Start with 100 per group.

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 '{
    "industry": ["Retail", "Online and Mail Order Retail", "Retail Apparel and Fashion",
                 "Retail Health and Personal Care Products", "Retail Furniture and Home Furnishings"],
    "country": ["US"],
    "employeeRange": ["51-200", "201-500", "501-1000"],
    "jobLevel": ["VP", "Director"],
    "jobFunction": ["Advertising & Marketing"],
    "emailStatus": ["verified", "catch_all_valid"],
    "limit": 100
  }' > growth.json

Repeat with the operations and exec filters from Step 1, saving operations.json and exec.json. That spends 300 records. Each person returned counts one record, and an empty page costs nothing.

To get more than one page, read meta.nextCursor and send it back as cursor. One search pages to 10,000 rows. If meta.depthCapped is true, narrow the filters instead of walking further.

If you already hold a target account list, search by domain. This lists the people at one company:

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

Step 5: Enrich the people you will contact first

Search gives you the profile. Enrich adds career history and the email, and you choose which people get it. Take the top 50 by fit, not all 300.

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 '{ "person_id": "PERSON_ID_FROM_SEARCH", "reveal_email": true }'

Enrich takes exactly one of linkedin_url, email, phone or person_id. Since October 2026 it returns past roles, education and certifications under resume_data. A past role at a marketplace or a 3PL is a useful opener for the growth and operations lists. Read email_status before you send, because bounced emails are not refunded.

An enrichment that finds nothing returns 404 and costs nothing. A phone lookup is a separate call, GET /v2/people/phone, and costs one record.

Keep the enriched set small on purpose. Fifty well-matched people with a verified address give you a clean read on the angle within a week. Three hundred half-matched ones give you noise and a bounce problem.

Step 6: Write one angle per role

The list is the easy half. Reply rates come from sending each group a reason that fits its job. Use this prompt in any LLM, with the person's title and the one thing you sell.

text
You write a 60-word cold email to {title} at a US ecommerce brand with {headcount} employees.
Our product: {one sentence}.
Angle for this role group:
- growth: lead with conversion or CAC, one number you can prove.
- operations: lead with ship time, returns or cost per order.
- exec: lead with margin and payback in months.
Rules: no flattery, one question at the end, no claim you cannot back.

Three angles to start from:

  • Growth: peak season is a fixed deadline. Offer the result they can have live before it, not a feature list.
  • Operations: returns and shipping errors are measured per order. Quote the unit they already track.
  • Exec: at 200 to 1,000 people, margin is the board's question. Give payback in months and a way to test small.

Do not invent a customer result for the email. If you have none, offer a short pilot instead.

Send one group first and use its replies to pick the line for the next. Keep each group in its own campaign so you can compare reply rates by role, not by guess.

Before you move on, check the list for two common faults. First, marketplaces and agencies filed under retail or marketing: scan the first 20 company names and add excludeCompanyName for any that are not your buyer. Second, duplicates across groups: a founder can appear as exec and as growth, so dedupe on person_id before you load a sequencer. LeadOcean has no sequencer, so export or copy the rows into the tool you already use.

What you get

This is a real count run on 2026-10-21 with the MCP tool leadocean_count_leads: US, the five retail industry values from Step 3, 51 to 1,000 employees, VP and C-Team, default mailable counting.

json
{
  "total": 25660,
  "totalAll": 89621,
  "distinctCompanies": 3662,
  "facets": {
    "seniority": [
      { "value": "c_suite", "count": 11929 },
      { "value": "owner", "count": 8453 },
      { "value": "vp", "count": 5278 }
    ]
  }
}

That is 25,660 people with a mailable address, across 3,662 companies. The same filters without an email condition match 89,621 people. Mailable here means verified, catch_all_valid or catch_all, not a phone count.

Cutting the same industries to Director and VP by function, on the same date:

Role groupFiltersMailable peopleCompanies
GrowthVP, Director, Advertising & Marketing3,0631,170
OperationsVP, Director, Operations or Supply Chain & Logistics1,965934

The exec group (C-Team only) counts 20,382 mailable people at 3,432 companies on the same date. The 25,660 above adds VPs, so it overlaps the growth and operations rows. Dedupe on person_id so you do not mail one person twice.

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

json
{
  "success": true,
  "data": [
    {
      "profile_data": {
        "profile_full_name": "Jane Doe",
        "profile_headline": "VP Marketing at Acme"
      },
      "contact_data": {
        "has_email": true,
        "has_phone": false,
        "email_status": "verified",
        "contact_current_experiences": [
          { "company_name": "Acme", "company_domain": "acme.com", "job_title": "VP Marketing" }
        ]
      },
      "meta": { "source_ids": { "person_id": "PERSON_ID" } }
    }
  ],
  "meta": { "nextCursor": "CURSOR", "depthCapped": false }
}

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerCheck echo $LEADOCEAN_API_KEY and send it as the x-api-key header, not a bearer token.
429More requests a second than your plan allows: 5 on Free, 200 on AgencyWait for the Retry-After header, then slow the loop.
402The 1,000 Free records are spentCheck GET /v1/usage, then move to Solo at $97 a month or Agency at $497 a month.
Empty resultsA filter value is not an exact enum string, such as United States for countryUse US, and look values up with GET /v1/enums or leadocean_list_enum_values.
Total looks too smallThe default count only includes mailable addressesAdd emailStatus with all values to see the unfiltered total.
Export refusedBulk CSV export is not on FreeUse search with a cursor, or upgrade. Exports take up to 50,000 rows a request and 500,000 a day.

FAQ

Is there an ecommerce industry filter?

Not one. Online sellers are filed under several retail values, so use the retail family and confirm each string with the enum lookup. Pure-play stores are also easier to find by domain once you have a target list.

Who is the economic buyer at an ecommerce brand?

At 50 to 200 employees, the founder or the head of ecommerce. At 500 or more, a VP in marketing or operations owns the problem and finance signs. Search all three groups, and rank by the one that feels the pain you fix.

How many records will this cost?

The counts are free. Pulling 100 people per group for three groups, plus 50 enrichments, spends about 350 records. The Free plan holds 1,000 for life, so you can run the sample twice.

Can I reach these people by phone?

Yes, with a separate call. GET /v2/people/phone costs one record, and a count with hasPhone is a phone count, not a mailable one. Label it by what you filtered.

When do I need a paid plan?

When you pass 1,000 records, need bulk CSV export, or run above 5 requests a second. Solo at $97 a month suits one person. Agency at $497 a month suits a team. See pricing.

For other verticals, see the blog hub and the guides for web3, travel and telecom.

Size your ecommerce market for free, then pull the first 1,000 records

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

Get your free API key →