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

HubSpot recipe

LeadOcean + HubSpot: find company lookalikes

Tag a best customer in HubSpot. A workflow pulls similar companies from LeadOcean and creates them as HubSpot companies.

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

You get a HubSpot workflow that takes a company you already sell to and creates similar companies in HubSpot. LeadOcean does the matching: same industry, same headcount bracket, same headquarters country. There is no HubSpot listing for LeadOcean, so the call is a plain HTTP request to https://api.leadocean.io from one custom code action.

How it works

The trigger is a checkbox on the seed company. The action reads the seed from LeadOcean, searches for matches and writes them to HubSpot. HubSpot says custom code actions need a Data Hub Professional or Enterprise account (HubSpot docs, October 2026).

  1. Create a LeadOcean key. Sign up at app.leadocean.io/register. No card, 1,000 records.
  2. Add two secrets. In the custom code action, click Add secret. Add LEADOCEAN_API_KEY and a HubSpot private app token with company write scope. Secrets reach the code as process.env variables (HubSpot docs, October 2026).
  3. Create a company-based workflow. Create a company property lookalike_seed (single checkbox). Enroll companies where it is true and Company domain name is known.
  4. Add a Custom code action. Language Node.js. Add domain as an input property. Paste the code below.
  5. Size the list first. Call GET /v1/companies/count with the same filters. It is free and returns an exact total, so you know how many records a run will spend.
  6. Test on one seed, then turn it on. A test spends up to 26 LeadOcean records: 1 seed and 25 matches.

LeadOcean matches on firmographic filters. It is not a model score. Say that to whoever reads the list.

Configuration

HubSpot lists axios as a supported Node.js library (HubSpot docs, October 2026). Company creation is POST /crm/v3/objects/companies, and domain is the unique identifier HubSpot uses to avoid duplicates (HubSpot docs, October 2026).

javascript
const axios = require('axios');
const LO = { headers: { 'x-api-key': process.env.LEADOCEAN_API_KEY } };
const HS = { headers: { Authorization: 'Bearer ' + process.env.HUBSPOT_TOKEN } };

exports.main = async (event, callback) => {
  const domain = event.inputFields['domain'];

  // 1 record: the seed
  const seed = (await axios.post('https://api.leadocean.io/v1/companies/enrich',
    { domain }, LO)).data.data.company_data;

  // up to 25 records: the lookalikes
  const found = (await axios.post('https://api.leadocean.io/v1/companies/search', {
    industry: [seed.company_industries[0].name2],
    employeeRange: [seed.company_employees.number_of_employees_code],
    hqCountry: [seed.company_primary_address.country_code],
    hasMailableContacts: true,
    limit: 25,
    fields: ['company_data.company_name', 'company_data.company_domain']
  }, LO)).data.data;

  let created = 0;
  for (const c of found) {
    const d = c.company_data;
    if (!d.company_domain || d.company_domain === domain) continue;
    try {
      await axios.post('https://api.hubapi.com/crm/v3/objects/companies',
        { properties: { name: d.company_name, domain: d.company_domain } }, HS);
      created++;
    } catch (e) { /* duplicate or bad row: skip it */ }
  }
  callback({ outputFields: { created } });
};

The seed fields come from company_data: company_industries[0].name2, company_employees.number_of_employees_code and company_primary_address.country_code (LeadOcean docs). Any of them can be null, so guard them in production. Check the same search outside HubSpot first:

bash
curl -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"],"employeeRange":["51-200"],"hqCountry":["US"],"limit":25}'

Industry and headcount values are exact strings. Look them up free with list_enum_values or GET /v1/enums (LeadOcean docs, September 2026).

Field mapping

LeadOcean fieldHubSpot propertyNote
company_data.company_namenameSent on create.
company_data.company_domaindomainPrimary unique identifier in HubSpot. Never create without it.
seed domaincustom lookalike_ofCreate a text property so you can report by seed.
run datecustom lookalike_added_onDate property. Lets you filter new rows.

Cost at 10,000 rows

10,000 lookalikes cost $97 on LeadOcean Solo, plus HubSpot Data Hub Professional. Take 400 seeds at 25 rows each: 10,000 search records plus 400 seed lookups. Solo allows 100k search records every 5 hours (LeadOcean pricing). Free stops at 1,000 records, which covers about 38 seeds.

LeadOceanHubSpot
PlanSolo, $97 a month, flatData Hub Professional
PriceNo per-record price, fair-use paceListed on HubSpot pricing
Free tier1,000 records, onceWorkflows with webhooks and custom code are not on it

Teams running many seeds a day should read the Agency plan on the pricing page.

Troubleshooting

SymptomCauseFix
400 from LeadOcean searchIndustry or range is not an exact enum valueFetch the value with GET /v1/enums and map it.
Empty found listFilters too narrowDrop hqCountry, then hasMailableContacts, one at a time.
401 from LeadOceanWrong secret nameMatch the secret name to process.env.
402 from LeadOceanThe free 1,000 records are spentMove to Solo. Free records do not renew.
429 from LeadOceanOver the rate limit5 requests a second on Free, 50 on Solo (LeadOcean docs, September 2026).
401 from HubSpotToken lacks company write scopeAdd the scope to the private app.
Same seed runs twiceCheckbox stays trueAdd a final action that clears lookalike_seed.

FAQ

Can I use the Send a webhook action instead of code?

Possibly. The action sends POST or GET requests and can set a header API key (HubSpot docs, October 2026). It needs Data Hub Professional or Enterprise too. The seed's industry must match a LeadOcean enum, so code is simpler.

Is this a similarity score?

No. It is a filter match on industry, headcount and country. See the lookalike skill for the same logic in Claude.

Do I need HubSpot Data Hub?

For the workflow, yes. Without it, run the same script from cron against the HubSpot companies API.

Where else can I find companies?

Turn your best HubSpot customers into a target list

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

Get your free API key →