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

How-to guide

How to build a cold calling tech stack (for a small agency)

Five layers, one of them is data. Here is the data layer with real queries, then the hand-off to your dialer and CRM.

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

A cold calling tech stack is five layers: a list, phone numbers, a dialer, a CRM and a scheduler. Most guides spend their words on the dialer. The layer that decides your connect rate is the data, so this guide builds that one with real queries and then hands off.

TL;DR

  • Build the list and phone layer first with three calls: size, search, phone lookup. It takes about 30 minutes.
  • A 50-person test list spends about 100 LeadOcean records at most: 50 from search, up to 50 from phone lookups. Sizing is free.
  • Dialer, CRM and scheduler are your pick. They only need a CSV or a webhook from the data layer.

Prerequisites

  • A LeadOcean account and key. The free plan has 1,000 records for life, no card, 5 requests a second.
  • The key in your shell: export LEADOCEAN_API_KEY=...
  • curl and jq.
  • A dialer and a CRM that accept CSV import. Any will do.

Step 1: Pick the five layers

Write the stack down before you buy anything. Each layer has one job and one hand-off.

LayerJobHand-off
ListWho to callPerson IDs or LinkedIn URLs
Phone dataA number per personPhone, type, best first
DialerPlace the callsCSV or webhook in
CRMLog outcomesContact and call records
SchedulerBook the meetingLink in the follow-up email

An agency write-up lists the same layers (BetterContact, cold calling tech stack, September 2026). LeadOcean covers the first two. It has no dialer, CRM or sequencer, so you bring those.

Step 2: Size the call list for free

Count before you spend. A count costs no records, so ask as often as you like.

Use the MCP tool leadocean_count_leads from any connected agent, or the REST search with count=true as a query parameter and limit=1:

bash
curl -s "https://api.leadocean.io/v1/people/search?count=true&limit=1" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "jobLevel": ["VP", "Director"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["US"],
    "industry": ["Marketing Services"],
    "hasPhone": true
  }' | jq '.meta'

The filters are arrays of exact strings. If a value comes back empty, resolve it with leadocean_list_enum_values or GET /v1/enums first.

Count it for companies too. GET /v1/companies/count is free and returns breakdowns by industry, headcount band and HQ country.

Step 3: Pull the first 50 people

Search with the same filters, limit 50. Each person returned costs one record.

bash
curl -s "https://api.leadocean.io/v1/people/search" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "jobLevel": ["VP", "Director"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["US"],
    "industry": ["Marketing Services"],
    "hasPhone": true,
    "limit": 50
  }' > page1.json

jq -r '.meta.nextCursor' page1.json

To get the next page, add "cursor": "<nextCursor>" to the body. One search pages to 10,000 rows. Past that, narrow the filters instead of walking further.

Want only companies on a given tool? Add technologyCategories (for example CRM) to the filter. That covers about 7.8M crawled sites.

Step 3b: Narrow by what the company runs

Filter on detected technology so the first line of the call says something true about the company.

bash
curl -s "https://api.leadocean.io/v1/people/search?count=true&limit=1" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "jobLevel": ["VP", "Director"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["US"],
    "technologyCategories": ["CRM"],
    "employeeRange": ["51-200", "201-500"],
    "hasPhone": true
  }' | jq '.meta'

Enum values are exact strings. employeeRange takes brackets like 51-200, and technologyCategories has 105 values. Resolve any you are unsure of with leadocean_list_enum_values.

Step 4: Fetch the phone numbers

hasPhone: true tells you a number exists. To read it, call GET /v2/people/phone once per person, with the ID from the search row (meta.source_ids.person_id) sent as contact_id.

bash
for id in 1234567 1234568; do
  curl -s "https://api.leadocean.io/v2/people/phone?contact_id=$id" \
    -H "x-api-key: $LEADOCEAN_API_KEY" | jq '.data'
  sleep 0.25
done

This costs one record per call, including an answer of found: false. A 404 (no record for that person at all) costs nothing. The sleep keeps you under the 5 requests a second on Free. Agency allows 200.

For lists beyond a few hundred rows, skip the loop. Use POST /v1/exports (not on Free) or the Exports page in app.leadocean.io: filter builder, column picker, price preview, CSV download. An export takes up to 50,000 rows a request and 500,000 a day.

Step 5: Load the dialer and CRM

Both take a CSV. Map four columns and you are done.

CSV columnDialer fieldCRM field
phone_1_numberPhonePhone
email_1_addressEmailEmail
full nameNameName
companyCompanyAccount

Keep the person_id column. It stays stable across exports, so you can de-duplicate on re-import. Check each tool's own import docs for the exact header names. Read email_1_status before any email follow-up.

Step 6: Let an agent do the sizing

If you work in Claude Code or another MCP client, connect https://api.leadocean.io/mcp (OAuth sign-in, no key pasted). Then ask in plain words:

text
Count US VP and Director level sales leaders at Marketing Services companies
with a phone number on file. Use leadocean_count_leads only. Do not search.
Then repeat for employeeRange 51-200 and report both totals.

The count tools are free, so an agent can iterate on filters without spending a record. Keep search, get_lead and find_phone for the final list.

What a first week costs

Plan the spend by layer. Data is the only one LeadOcean prices here.

ItemRecords
Sizing counts, any number0
Search, 50 people50
Phone lookups, up to 50up to 50
Lookups that return 4040

That fits inside the Free plan's 1,000 records ten times over. A team calling daily outgrows it fast. Agency at $497 a month has a fair-use pace instead of credits, plus exports of 50k rows a file. Solo is $97 a month for one person. See pricing for what each plan includes.

What you get

Step 2 count run on 2026-10-21 with leadocean_count_leads (free):

json
{
  "filters": "jobLevel VP or Director, jobFunction Sales & Business Development, country US, industry Marketing Services, hasPhone true",
  "total": 3774,
  "totalIsExact": true,
  "distinctCompanies": 1528,
  "credits": 0
}

That is a phone-flagged count, not a mailable count. It filtered on hasPhone, so it says nothing about email deliverability.

The phone call returns this shape (response shape from the API reference, placeholder values):

json
{
  "success": true,
  "data": {
    "found": true,
    "best": { "phone": "+1 415 555 0133", "type": "mobile" },
    "phones": [
      { "phone": "+1 415 555 0133", "type": "mobile" },
      { "phone": "+1 415 555 0134", "type": "office" }
    ]
  }
}

The array is ordered best first. Each number carries only phone and type. The response has no meta, so read spend from GET /v1/usage.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerRe-copy the key from app.leadocean.io and check $LEADOCEAN_API_KEY is exported
429Above the plan's rate limit (5 a second on Free, 200 on Agency)Honour Retry-After, add a sleep, or move up a plan
402Records spent (Free is 1,000, once)Check GET /v1/usage, then pick a paid plan on the pricing page
404 on phoneNobody matched the ID or URLNothing to fix and nothing billed. Skip the row
Empty search resultsEnum value spelled wrong, such as vp for jobLevelUse VP. Resolve values with GET /v1/enums
Export refusedOver 50,000 rows a request, 500,000 a day, or Free planSplit the export by country or headcount band. Bulk CSV needs a paid plan

FAQ

What is the minimum cold calling tech stack?

A list with phone numbers, a dialer and a place to log outcomes. A spreadsheet can be the CRM for the first month. Add the scheduler when you have a booked-meeting problem.

Does LeadOcean include a dialer?

No. LeadOcean is the data layer. It has no dialer, sequencer, CRM or Chrome extension. The API and the Exports page feed whichever dialer you choose.

How many records does a call list cost?

One record per person you receive, plus one per phone lookup. Counts, empty pages and a phone 404 are free. A phone lookup that answers found: false still costs one record. A 50-person list is at most about 100 records. See pricing.

Can I filter by the tech a company runs?

Yes. Use technologies or technologyCategories on search. The tech stack lookup tools guide compares options, and the tech stack checker and tech stack qualifier skill cover single-company checks.

Can an AI agent run these steps?

Yes. The hosted MCP server at https://api.leadocean.io/mcp has 13 tools, including free counting and filter lookup, so an agent can size a list before it spends anything.

Build your call list with 1,000 free records

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

Get your free API key →