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

How-to guide

How to Get a Websearch API (with a People Data Layer)

A websearch API returns pages. It does not return people. Here is how to get a key, make the first call, and pair it with a B2B search API.

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

To get a websearch API, sign up with a search provider, create a key, and send a query over HTTPS. You get back JSON with titles, URLs and snippets. This guide shows that flow, then adds the part a websearch API cannot do: turning a result into a named person with a work email.

Provider details differ, so the websearch steps use a placeholder host. The LeadOcean steps are real requests against https://api.leadocean.io.

TL;DR

  • A websearch API returns web pages. A B2B search API returns people and companies. Most outbound and research workflows need both.
  • Takes about 20 minutes and spends 6 LeadOcean records of the 1,000 free ones. Counts cost nothing.
  • Websearch gets you the signal (a funding post, a launch). LeadOcean gets you the VP behind it.

Prerequisites

  • An account with a websearch provider. Read its docs for the endpoint, auth header and rate limit.
  • A LeadOcean account. The free plan gives 1,000 records one-off, no card: register here.
  • curl and jq.
bash
export SEARCH_API_KEY="paste-your-search-key-here"
export LEADOCEAN_API_KEY="paste-your-leadocean-key-here"

Step 1: Decide which kind of search you need

Pick the API by the shape of the answer you want. This one choice saves most of the rework.

You wantYou needExample question
Pages, snippets, newsA websearch API"What did Acme announce this month?"
People at companiesA B2B people search API"Which VPs of Sales work in Canada?"
Both, joinedWebsearch, then B2B search"Who runs sales at the company that just raised?"

A websearch API cannot tell you who the VP of Sales is with a verified email. It can tell you which page mentions them. Do not ask one tool to do the other's job.

Step 2: Create the websearch key

Sign up with the provider and open its dashboard. Generate a key and copy it once. Store it in an environment variable, never in code or a repo.

Check three things in the docs before you write code. These decide whether the API fits your use.

  • The auth header name and format.
  • The rate limit, in requests per second or per minute.
  • What a call costs: per request, per result, or per credit.

Providers price differently, so compare on the cost of your real volume, not the headline number.

Step 3: Make the first websearch call

Send one query and read the raw JSON before you build anything on it. The host and parameter names below are placeholders: take the real ones from your provider's docs.

bash
curl -s -X POST "https://search.example.com/v1/search" \
  -H "Authorization: Bearer $SEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Acme Series B funding announcement",
    "country": "us",
    "num_results": 5
  }' | jq '.results[] | {title, url, snippet}'

Most providers return a ranked list with a title, a URL and a snippet per hit. The output below is an illustration of that common shape, not a real response.

json
{
  "title": "Acme raises Series B to expand its platform",
  "url": "https://news.example.com/acme-series-b",
  "snippet": "Acme, a workflow software company, announced a Series B round..."
}

Pull the company domain out of the hit (here, acme.com). That domain is the key into the next step.

Step 4: Size the people list at that company for free

Send count=true and limit=1 as query parameters and LeadOcean returns a total without spending a record. The filters go in a flat JSON body, and every filter is an array of strings.

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 '{
    "domain": ["acme.com"],
    "jobLevel": ["VP", "C-Team"]
  }' | jq '.meta'

meta.total is capped at 100,000. Enum values are exact strings: VP and C-Team work, vice president returns nothing. List the allowed values with GET /v1/enums/job_level.

Step 5: Pull the people and enrich one

Search the same filter without count, then enrich the person you want. Search rows are thin and carry flags only. Enrich takes exactly one of linkedin_url, email, phone or person_id.

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 '{
    "domain": ["acme.com"],
    "jobLevel": ["VP", "C-Team"],
    "limit": 5
  }' > people.json

PID=$(jq -r '.data[0].meta.source_ids.person_id' people.json)

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\": \"$PID\", \"reveal_email\": true}"

The search spends 5 records, one per person returned. The enrich spends 1. If we hold nothing for that person you get a 404 and no charge.

To page further, pass meta.nextCursor back as cursor, unchanged. One search pages to 10,000 rows.

Step 6: Join both in one script

Glue the two calls together once, then reuse it. Save this as people-for-hit.sh and run it with a domain. It takes a domain from a websearch hit and returns a free count of VP and C-Team people there before it spends anything.

bash
#!/usr/bin/env bash
DOMAIN="$1"

TOTAL=$(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 "{\"domain\": [\"$DOMAIN\"], \"jobLevel\": [\"VP\", \"C-Team\"]}" \
  | jq -r '.meta.total')

echo "$DOMAIN: $TOTAL leadership people on file"

Set a budget before you loop over many hits. A count is free, so run it for every hit and only pull rows where the total is small enough to read. Keep the websearch call and the people call separate so you can swap either provider later.

Two habits keep this cheap. Cache the websearch result by query, so a repeated query does not cost a second call. Cache the LeadOcean record by person_id, because a record you already hold does not need a second pull.

Step 7: Let an agent do both

If you use an AI client, skip the glue code. The hosted MCP server at https://api.leadocean.io/mcp signs in with OAuth, so there is no key to paste. It has 13 tools, and leadocean_count_leads, leadocean_count_companies, leadocean_list_filters and leadocean_list_enum_values are free.

text
Using web search, find the company that announced a Series B this week.
Take its domain. Count VPs and C-Team people there with leadocean_count_leads.
If the count is under 50, show me the first 5 and tell me how many records that spent.

Web search comes from your client. People data comes from LeadOcean. The agent should count first and spend records only after you see the total.

What you get

The free MCP tool leadocean_count_leads ran on 2026-10-21 for VPs in Sales & Business Development in Canada. It counts mailable people by default, meaning a verified, catch_all_valid or catch_all email.

json
{
  "query": "jobLevel VP, jobFunction Sales & Business Development, country CA",
  "total": 5574,
  "totalIsExact": true,
  "totalAll": 18800,
  "distinctCompanies": 3873,
  "credits": 0
}

That is 5,574 mailable VPs of Sales in Canada on 2026-10-21. Without the email filter the same filters match 18,800 people across 3,873 employers. It is a mailable count, not everyone who matches the other filters.

A record-level response has the shape below (response shape from the API reference, placeholder values). Contact points appear only after enrich with reveal_email:

json
{
  "success": true,
  "data": {
    "profile_data": { "name": "Jane Doe", "title": "VP Sales", "company": "Acme" },
    "contact_data": {
      "has_email": true,
      "has_phone": true,
      "email_status": "verified",
      "contact_emails": [
        { "email": "jane.doe@acme.com", "type": "work", "status": "verified" }
      ],
      "contact_phones": [
        { "phone": "+14155550133", "type": "mobile", "priority": 1 }
      ]
    }
  },
  "meta": { "source": "leadocean" }
}

Read email_status before you send anything. Each record carries its own fetched_at date, and the dataset refreshes monthly.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key headerRe-export $LEADOCEAN_API_KEY and check the header name
402Out of records. On Free the 1,000 are a one-off allowanceMove to Solo at $97 a month, or lower limit
429Above the plan's rate limit (5 requests a second on Free, 200 on Agency)Honour the Retry-After header and back off
Empty dataA filter value is not an exact enum stringList values with GET /v1/enums/job_level and copy one
meta.depthCapped is trueOne search pages to 10,000 rowsNarrow the filters and run several smaller searches
Export refusedOver 50,000 rows a request or 500,000 a daySplit the export into several requests

FAQ

What is the difference between a websearch API and a B2B data API?

A websearch API returns ranked web pages. A B2B data API returns structured people and company records. See what a websearch API is for the first, and API for the general term.

Does LeadOcean offer a websearch API?

No. LeadOcean is a people and company data API with a hosted MCP server. It does not return web pages. Pair it with the search provider of your choice.

Is a websearch API a REST API?

Most are. You send an HTTPS request and read JSON. See RESTful API for what that means.

How much does LeadOcean cost?

Free is $0 with 1,000 records for life and no card. Solo is $97 a month, Agency is $497 a month, and Platform is $1,997 a month. Paid plans have a fair-use pace, not credits. See pricing.

Add a people layer to your search pipeline with a free API key

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

Get your free API key →