Intent-based marketing means contacting accounts because of something they did or changed, not because they fit a list. LeadOcean does not sell browsing-behaviour intent. It gives you public, checkable signals: installed technology, headcount band, seniority and role history. This guide turns those into an audience an AI agent can size, rank and pull.
TL;DR
- You will define an intent audience as filters, size it for free, and pull a ranked sample.
- It takes about 30 minutes. Sizing and counts cost 0 records. The sample page costs 100 records, so it fits inside the Free plan's 1,000.
- The signal is a proxy, not a purchase-intent score. You test it with a small send before you scale it.
Prerequisites
- A LeadOcean account. The Free plan is $0, 1,000 records for life, no card, 5 requests a second.
- An API key in your shell:
export LEADOCEAN_API_KEY=... - Optional: an MCP client (Claude, ChatGPT or Claude Code) connected to
https://api.leadocean.io/mcpby OAuth. No key is pasted. curlandjq.
Step 1: Pick signals you can verify
Choose two or three signals that a buyer would show before they need you. Write each as a filter, not a feeling.
| Signal | LeadOcean filter | Why it counts |
|---|---|---|
| Runs the tool you replace or extend | technologies | Detected on the company website (about 7.8M crawled sites) |
| Right size to buy | employeeRange | Headcount band |
| Owner of the budget | jobLevel, jobFunction | Current role |
| New in the seat | resume_data on enrich | Role start dates, since 2026-10-17 |
Example hypothesis: US marketing leaders at 51-500 person companies that run HubSpot are buying marketing data this quarter.
Step 2: Size the audience for free
Use the count call before you pull anything. Over MCP the tool is leadocean_count_leads. Over REST, send count=true and limit=1 as query parameters.
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 '{
"technologies": ["HubSpot"],
"jobFunction": ["Advertising & Marketing"],
"jobLevel": ["VP", "C-Team"],
"employeeRange": ["51-200", "201-500"],
"hqCountry": ["US"]
}' | jq '.meta'The call returns the total and spends nothing. meta.total is capped at 100,000.
An AI agent can do the same through MCP. Paste this prompt into your client:
Use leadocean_count_leads. Technology HubSpot, job function
Advertising & Marketing, job level VP or C-Team, employee range
51-200 and 201-500, HQ country US. Report the total, totalAll and
distinctCompanies. Do not call any tool that spends records.Step 3: Compare against the unfiltered base
A signal is only useful if it narrows the list. Run the same count without technologies and compare.
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 '{"jobFunction":["Advertising & Marketing"],"jobLevel":["VP","C-Team"],
"employeeRange":["51-200","201-500"],"hqCountry":["US"]}' | jq '.meta.total'On 2026-10-21 the HubSpot signal cut 23,810 mailable people to 5,467. That is 23% of the base, spread over 3,401 companies. If a signal keeps 90% of the list, it is not a signal.
Step 4: Pull a ranked sample
Pull one page of 100. Order is yours to decide, so add a second filter that separates good fits from the rest, such as seniority.
curl -s https://api.leadocean.io/v1/people/search \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
-d '{
"technologies": ["HubSpot"],
"jobFunction": ["Advertising & Marketing"],
"seniority": ["vp", "c_suite"],
"employeeRange": ["51-200", "201-500"],
"hqCountry": ["US"],
"emailStatus": ["verified"],
"limit": 100
}' > sample.json
jq '.meta' sample.jsonThis spends 100 records. Page further with the cursor value in meta. One search pages to 10,000 rows. If meta.depthCapped is true, narrow the filters.
Step 5: Add a timing signal with enrichment
Fit is not timing. A person who changed role recently is more likely to review tools. Enrich the people you shortlist by the id each row carries at meta.source_ids.person_id, and read the role dates.
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_SAMPLE"}' \
| jq '.data.contact_data.contact_current_experiences[0].start_date, .data.resume_data.experiences[0:2]'Keep people whose current role start_date falls in the last 6 months. Each past role carries job_title, company_name, start_date and end_date. Past employers have no company_id yet, so match them by name. An enrichment that finds nobody is a 404 and costs nothing.
Step 6: Hand the ranking to an AI agent
Give the agent your rules and the sample, and let it score. Keep the rules short and checkable.
Score each row 0-3 from sample.json:
+1 seniority is vp or c_suite
+1 company headcount band is 51-200 or 201-500
+1 current role started within 6 months (from enrich)
Return only rows scoring 2 or more. Never invent a field that is
missing from the row. Say "not in data" instead.The agent ranks what the data holds. It does not add intent that is not there.
What you get
Count output from leadocean_count_leads on 2026-10-21 (technology HubSpot, marketing function, VP or C-Team, 51-500 employees, HQ US, default mailable filter):
{
"total": 5467,
"totalIsExact": true,
"totalAll": 14355,
"distinctCompanies": 3401,
"credits": 0
}The count uses the default mailable filter: verified, catch_all_valid or catch_all email. totalAll is the same filters with no email condition. The unfiltered base (no technology) returned 23,810 mailable and 80,678 in total, at 14,358 companies.
Each row in the sample has this shape. It is the response shape from the API reference, with placeholder values.
{
"profile_data": { "profile_full_name": "Jane Doe" },
"contact_data": {
"has_email": true,
"email_status": "verified",
"contact_current_experiences": [
{ "job_title": "VP Marketing", "company_name": "Acme", "company_domain": "acme.com", "start_date": "2026-06-01" }
]
},
"meta": { "source_ids": { "person_id": "123456789" } }
}A search row carries email flags, not the address. Enrich with reveal_email set to true to get it.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key | Check $LEADOCEAN_API_KEY is exported in this shell |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Honour Retry-After, or batch with fewer calls |
| 402 | Out of records | Free is 1,000 for life. Move to Solo ($97 a month) or Agency ($497 a month) |
| Empty results | A bad enum value, such as VP Marketing in jobLevel | Use leadocean_list_enum_values. Job levels are C-Team, VP, Director, Manager, Staff, Other |
meta.depthCapped is true | One search reached 10,000 rows | Narrow the filters instead of paging on |
| Unsupported filters in a count | Funding, revenue or HQ city filters do not count reliably | Count without them, then add them at search time |
FAQ
Does LeadOcean sell intent data?
No. It does not track who is reading what. It returns public attributes you can verify: technology on the website, headcount, role and role history. Treat them as intent proxies.
How many records does this cost?
Sizing is free. The 100-row sample costs 100 records, and enrichment costs one record per person found. The whole recipe fits inside the Free plan.
Can I run this from Claude or ChatGPT?
Yes. Connect https://api.leadocean.io/mcp and ask for the count first. In ChatGPT, add it as a plugin: chatgpt.com/plugins, the + button, Add custom MCP server, sign in with OAuth, then type @ in a chat to select it. The count tools spend nothing. The search, get_lead, find_phone, get_company and export tools spend one record per person or company returned.
How do I test if the signal works?
Send 100 messages to the signal group and 100 to a matched group without it. Compare replies after two weeks. Do not scale a signal you have not tested.
For more on picking an audience, read lead generation tactics, B2B data segmentation and lead generation for marketing agencies. Plans are on /pricing.
Size your intent audience for free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →