TL;DR
- An API for AI agents is a tool the model calls to read or change something outside itself. For B2B data that means search, count and enrich, behind typed inputs.
- It takes about 40 minutes and spends about 6 LeadOcean records: 5 for a sample search and 1 for one enrichment. Counts are free.
- Use the hosted MCP server when a client such as Claude Code drives the agent. Use one REST tool when you own the agent loop.
Most explainers split the space into agent frameworks (the reasoning loop) and tool or data APIs (what the agent reads and writes). Crustdata's overview, checked October 2026, draws the same line. This page is the data-API half, with real requests.
Prerequisites
- A LeadOcean account from app.leadocean.io. The free plan has no card, 1,000 records for life and 5 requests a second.
- An API key exported as
$LEADOCEAN_API_KEY. Create it under API keys in the app. Free gets 1 key with search and enrich scopes. curl,jq, Python 3 withrequests, and Claude Code if you want the MCP path.
export LEADOCEAN_API_KEY="paste-your-key-here"Step 1: Size the audience before the agent touches it
Count first, because counting costs nothing and a bad filter costs records. Send count=true as a query parameter with limit at 1. The body is flat JSON and every filter is an array.
The example audience is AI engineering leaders in the US.
curl -s "https://api.leadocean.io/v1/people/search?count=true" \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
-d '{
"title": ["AI Engineer", "Machine Learning Engineer"],
"jobLevel": ["Director", "VP", "C-Team"],
"country": ["US"],
"emailStatus": ["verified", "catch_all_valid", "catch_all"],
"limit": 1
}' | jq '.meta'data comes back empty and meta.countOnly is true. meta.total is capped at 100,000, and totalIsExact tells you whether it is a floor.
Enum values are exact strings. C-Team works and CEO does not. Resolve a value before you guess, with GET /v1/enums/job_level or the free leadocean_list_enum_values tool.
Step 2: Connect the hosted MCP server
If an MCP client runs your agent, skip the glue code. The server is at https://api.leadocean.io/mcp, sign-in is OAuth 2.1 in the browser, and no key is pasted. In Claude Code:
claude mcp add --transport http leadocean https://api.leadocean.io/mcpThen open Claude Code, type /mcp, pick leadocean and sign in when the browser opens.
The Claude Code MCP docs, checked October 2026, recommend the HTTP transport for remote servers. The server exposes 13 tools. Seven spend nothing: leadocean_count_leads, leadocean_count_companies, leadocean_list_filters, leadocean_list_enum_values, leadocean_get_account, leadocean_get_export and leadocean_list_exports. The rest cost 1 record per person or company returned.
Test with a prompt that cannot spend anything:
Count US AI or machine learning engineering leaders at Director, VP or C-Team level. Count only. Do not pull anyone.
The model should call leadocean_count_leads. Setup details are on Connect LeadOcean MCP to Claude Code.
Step 3: Wrap the REST API as one tool
When you own the loop (OpenAI Agents SDK, LangGraph, your own code), give the model one narrow function instead of the whole API. The model fills typed arguments. Your code adds the key and the cap.
import os, requests
BASE = "https://api.leadocean.io"
HEAD = {"x-api-key": os.environ["LEADOCEAN_API_KEY"]}
MAX_ROWS = 5 # hard cap per call, whatever the model asks for
def search_people(titles: list[str], countries: list[str], limit: int = 5):
body = {
"title": titles,
"country": countries,
"jobLevel": ["Director", "VP", "C-Team"],
"emailStatus": ["verified", "catch_all_valid", "catch_all"],
"limit": min(limit, MAX_ROWS),
}
r = requests.post(f"{BASE}/v1/people/search", headers=HEAD, json=body, timeout=30)
r.raise_for_status()
return r.json()Describe it to the model with a JSON schema in your framework's tool format: titles and countries as arrays of strings, limit as an integer from 1 to 5. A search page returns up to 100 rows, so the cap lives in your code. Each person returned is one record, so limit: 5 spends 5.
Keep the key server-side. Never put it in the prompt or in a tool result the model can echo.
Step 4: Add an enrich tool the agent calls on purpose
Search returns a thin projection with no contact points. Enrichment fills the rest. It takes exactly one of linkedin_url, email, phone or person_id, and there is no name plus domain lookup. Search first, then enrich by person_id.
def enrich_person(person_id: str, reveal_email: bool = False):
r = requests.post(f"{BASE}/v1/people/enrich", headers=HEAD,
json={"person_id": person_id, "reveal_email": reveal_email}, timeout=30)
if r.status_code == 404:
return {"found": False} # nobody matched, costs nothing
r.raise_for_status()
return r.json()A 404 costs nothing, so the agent can try. Since October 2026 the response also carries career history in resume_data: past roles, education and certifications. Past employers have no company_id yet.
Step 5: Budget the loop
An agent that retries will spend. Read your balance before each run and stop below a floor. GET /v1/account is free.
curl -s https://api.leadocean.io/v1/account -H "x-api-key: $LEADOCEAN_API_KEY" | jq .Also handle 429. Free allows 5 requests a second, Solo 50, Agency 200 and Platform 10,000, per account. Honour the Retry-After header. One search pages to 10,000 rows (meta.depthCapped), so narrow filters instead of walking the index.
Paid plans use a fair-use pace, not credits. Solo is $97 a month and Agency is $497 a month, with 5 keys. See pricing. If you embed the data in a product you resell, that is Platform at $1,997 a month.
What you get
The Step 1 filters, run through the free leadocean_count_leads tool on 2026-10-21 (facets off, trimmed):
{
"total": 159,
"totalIsExact": true,
"totalAll": 394,
"distinctCompanies": 134,
"credits": 0,
"unsupportedFilters": []
}That is 159 people with a verified, catch_all_valid or catch_all email, across 134 employers. Without the email condition the same filters match 394 people. The number moves as the data does.
A person record from enrich has this shape, from the API reference (api.leadocean.io/openapi.json), with placeholder values:
{
"profile_data": { "profile_full_name": "Jane Doe" },
"contact_data": {
"has_email": true,
"has_phone": true,
"email_status": "verified",
"contact_emails": [{ "email": "jane.doe@acme.com" }]
},
"resume_data": { "experiences": [], "educations": [] },
"meta": {}
}contact_emails appears only when reveal_email is true. Fields inside profile_data appear only when we hold them.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key | Re-export $LEADOCEAN_API_KEY and send it in the x-api-key header. |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Back off for Retry-After seconds. Queue the agent's calls. |
| 402 | The free plan's 1,000 one-off records are spent | Check GET /v1/account, then move to Solo ($97 a month) or Agency ($497 a month). |
| Empty results | A bad enum value, such as CEO for jobLevel | Look up the exact string with GET /v1/enums/job_level. |
unsupportedFilters not empty | A filter the count cannot apply | Drop it and count again, then apply it at search time. |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the filters into several exports. Bulk CSV is not on Free. |
FAQ
What is an API for AI agents?
It is any interface an agent calls to get data or take an action outside the model. Frameworks run the reasoning loop. Tool and data APIs, like search and enrich, supply the facts the loop needs. See the glossary entry for API.
MCP or REST for an agent?
Use MCP when a client such as Claude Code or Cursor already runs the agent. Use REST when you write the loop, because you can cap rows and keep the key on your server. Both draw on the same data and the same record balance.
How do I stop an agent overspending?
Cap limit in the tool wrapper, read GET /v1/account before each run, and let the agent count before it searches. Counts, filter lookups and enrichments that find nothing are free.
Does it work for recruiting products?
Yes. Person enrich returns career history, which suits candidate workflows. See candidate enrichment APIs for recruiting platform builders.
Where is the builder page?
B2B data for AI agent builders covers the tools and plans in one place.
Give your agent B2B data. Start with the free count.
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →