Documentation

MCP for agents

The hosted server at https://api.leadocean.io/mcp gives any MCP client the same data the REST API does — over OAuth 2.1, so there is no key to paste and nothing to leak into a chat log.

How it works

The server speaks Streamable HTTP with OAuth 2.1. You add one URL in your client, it sends you to LeadOcean to sign in, you approve, and the tools appear. Your assistant never sees an API key.

A connection is tied to your account, and usage counts against the same records as the REST API — one balance, however you call it. You can see and revoke every connected app from API keys → Connected apps in your account.

One URL for every client. https://api.leadocean.io/mcp — that is the whole configuration. Everything below is just where each app wants you to paste it.

Add it to your client

ClientHow to add it
ClaudeSettings → Connectors → Add custom connector → paste the URL → Connect.
ChatGPTSettings → Security and login → Developer mode, then Connectors → Add → paste the URL, authentication OAuth.
Claude Codeclaude mcp add --transport http leadocean https://api.leadocean.io/mcp then claude mcp login leadocean.
Cursormcp.json: {"mcpServers":{"leadocean":{"url":"https://api.leadocean.io/mcp"}}}
Codexconfig.toml: [mcp_servers.leadocean] url = "https://api.leadocean.io/mcp" then codex mcp login leadocean.
VS Code.vscode/mcp.json: {"servers":{"leadocean":{"type":"http","url":"https://api.leadocean.io/mcp"}}}
Windsurfmcp_config.json with serverUrl set to the URL above.
Gemini CLIsettings.json with httpUrl set to the URL above, then /mcp auth leadocean.

Any client that supports remote MCP over HTTP will work, whether or not it is listed — there is nothing client-specific about the server.

Tool catalog

These are the exact descriptions the server gives the model, read live from the running server — so an agent can plan its work without ever reading this page.

leadocean_list_enum_values · Resolve enum values · free

Look up the exact strings a closed-list filter accepts. Industry has 534 values and country 254, so guessing fails: search here first, then pass the exact value to leadocean_search_leads or leadocean_search_companies. Free, and it never spends records.

InputTypeMeaning
nameenumWhich value set to read — ONE name per call.
qstringSubstring to search for, e.g. "software" or "germany". Omit to list from the start.
limitintHow many values to return (default 50, max 200).

leadocean_list_filters · List filters & schemas · free

Returns every filter that leadocean_search_leads and leadocean_count_leads accept, the exact enum values allowed (seniority, emailStatus, company size codes), the names of the response schemas (leadocean.person.v1, leadocean.company.v1) and which data sources are currently active. Free — call it once when you are unsure which values are valid instead of guessing.

leadocean_search_leads · Search leads (people) · 1 record

Find people by job title, seniority, country, industry, company domain, company size or free text. Returns up to `limit` THIN person records (leadocean.person.v1 projection): full name, headline, current job title and company (name, domain, industry, size), location (city, country), profile URL and the has_email / email_status / email_type flags — never email addresses or phone numbers (use leadocean_get_lead with reveal_email for those). Combine filters to narrow, e.g. title="CTO", seniority=["c_suite"], country=["DE"], minEmployees=50. Paginate with `cursor` (meta.nextCursor). Each returned record counts 1 against the monthly records quota (limit=25 → up to 25); the page is capped to what is left this month. Every row carries meta.source_ids.person_id (the record — pass it to leadocean_get_lead) and meta.source_ids.person_group_id (the person — equal across duplicate records of one human; compare it, never look it up). meta.unsupportedFilters lists any filter the active source ignored. By default this searches only people whose best email is `verified` or `catch_all` — the addresses worth sending to. To widen it, pass `emailStatus` yourself (the full enum opts out entirely, `["verified"]` narrows further), or pass `hasEmail` or `reachable`; any one of those replaces the default rather than adding to it. Paging is capped: one search pages through 10,000 rows by default, and on the page that reaches the cap meta.nextCursor is null and meta.depthCapped is true. That walk is over — retrying the same query returns no further cursors, and paging harder is never the fix. Narrow the filters and run several smaller searches instead (split by country, then industry, then headcount band, then title). The figure is per account: an account with a genuine large export to run can have it raised, so tell the user to ask support rather than looping around it. It counts rows PAGED THROUGH and is not the monthly records allowance, which is a separate limit and unaffected. The cursor itself is opaque and signed: pass back exactly the string meta.nextCursor gave you, unchanged. A cursor that has been edited, truncated or built by hand, or one minted for a different search, is refused with 400 "Invalid cursor"; so is any cursor issued before 2026-09-19, in which case start that query again from the first page. Do not store a cursor for later — it is a position in one walk, not a handle on a result set.

InputTypeMeaning
qstringFree text over name, headline, job title and company. A short query needs every word; a longer one needs most of them, so a five-word phrase behaves as a keyword search rather than an exact match. Prefer the structured filters below.
profileKeywordsstring[]The same as keywords — the person’s own profile text; kept under this name for clients that adopted it.
excludeProfileKeywordsstring[]Profile keywords to exclude.
titlestring[]Job title keywords, e.g. ["Head of Sales","VP Sales"]. Wrap a value in [brackets] for an exact match.
excludeTitlestring[]Job titles to exclude, e.g. ["assistant","intern"].
seniorityenum[]LeadOcean seniority band (finer than jobLevel).
jobLevelenum[]Seniority band of the current role.
jobFunctionenum[]Department of the current role.
countryenum[]Where the person is, ISO 3166-1 alpha-2, e.g. ["US","DE"].
continentenum[]Continent the person is in.
salesRegionenum[]Commercial region the person is in.
citystring[]City keywords for the person.
excludeCitystring[]Cities to exclude.
educationstring[]School, degree or year phrases, e.g. ["Stanford"].
minConnectionsintMinimum LinkedIn connections on the person's profile, 0–500.
domainstring[]Company website domains, e.g. ["stripe.com"].
companyNamestring[]Company name keywords.
excludeCompanyNamestring[]Company name keywords to exclude.
companyLinkedinstring[]Company LinkedIn URLs, e.g. ["https://www.linkedin.com/company/stripe"].
industryenum[]Company industry — 534 values; resolve with leadocean_list_enum_values before guessing.
excludeIndustryenum[]Industries to exclude; same 534 values.
companyTypeenum[]Legal type of the company.
employeeRangeenum[]Headcount bracket — cheaper and broader than minEmployees/maxEmployees.
minEmployeesintCompany headcount, lower bound — only records whose value we hold; one with no figure on file is never returned.
maxEmployeesintCompany headcount, upper bound — only records whose value we hold; one with no figure on file is never returned.
minRevenueintAnnual revenue in USD — only records whose value we hold; one with no figure on file is never returned.
maxRevenueintAnnual revenue ceiling in USD — only records whose value we hold; one with no figure on file is never returned.
minFoundedintYear the company was founded — only records whose value we hold; one with no figure on file is never returned.
maxFoundedintLatest year the company was founded — only records whose value we hold; one with no figure on file is never returned.
minFollowersintMinimum company LinkedIn followers — 0 means no minimum; any value of 1 or more matches only records whose figure we hold.
fundingTypeenum[]Type of the last funding round.
minFundingintTotal funding raised, USD — only records whose value we hold; one with no figure on file is never returned.
maxFundingintTotal funding raised, USD ceiling — only records whose value we hold; one with no figure on file is never returned.
minLastFundingYearintFunded no earlier than this year — only records whose value we hold; one with no figure on file is never returned.
maxLastFundingYearintFunded no later than this year — only records whose value we hold; one with no figure on file is never returned.
investorsstring[]Lead investor name keywords, e.g. ["Sequoia"].
naicsstring[]NAICS industry codes, e.g. ["5415"].
sicstring[]SIC industry codes.
keywordsstring[]Keywords in the person’s own profile: headline, summary, skills and job descriptions — the PERSON’s text, not the employer’s (for the company’s text search companies, or filter people by industry / companyName). Each value is a phrase whose words must all appear; several values OR together.
excludeKeywordsstring[]Profile keywords to exclude.
hqCountryenum[]Company headquarters country, ISO 3166-1 alpha-2.
hqCitystring[]Company headquarters city keywords.
hqStatestring[]Company headquarters state or region.
hqContinentenum[]Continent of the company headquarters.
hqSalesRegionenum[]Commercial region of the company headquarters.
technologiesstring[]Technologies detected on the company website (LeadOcean data only).
technologyCategoriesenum[]What the detected technology is for, e.g. Analytics or CDN, rather than its name (own data only; covers the ~7.8M crawled companies).
emailStatusenum[]Email deliverability (LeadOcean data only).
emailTypeenum[]Work or personal email (LeadOcean data only). Pair with emailStatus to ask for a deliverable WORK address.
hasEmailbooleantrue = only people with a known email, false = only those without (LeadOcean data only).
hasPhonebooleanOnly people with, or without, a known phone number (own data only).
reachableenumHolding an email OR a phone — `strict` additionally requires the email to be verified, catch_all_valid or catch_all.
cursorstringOpaque page token — pass meta.nextCursor from the previous call back, exactly as it was returned, to get the next page. It is signed: an edited, truncated or hand-built cursor, or one from a different search, is refused with 400 "Invalid cursor". Null nextCursor means there are no more pages, either because the results ran out or because the search hit its depth cap (meta.depthCapped).
limitintRecords per page, 1–100 (default 25).
facetsbooleanAlso return counts per seniority / country / industry where the source supports it.

leadocean_count_leads · Count leads · free

Estimate how many people match a set of filters BEFORE pulling pages — use it to size an audience or check that a filter combination is not empty. Same filters as leadocean_search_leads. Returns the total, `totalIsExact` (false when counting stopped at the 100,000 cap, so the total is a floor — read the facets for the real shape), a one-record sample count, whether more pages exist, and facet counts. FREE: sizing an audience spends no records, however many times you ask. Pass facets=false for just the number, which is far quicker on a wide filter. By default this searches only people whose best email is `verified` or `catch_all` — the addresses worth sending to. To widen it, pass `emailStatus` yourself (the full enum opts out entirely, `["verified"]` narrows further), or pass `hasEmail` or `reachable`; any one of those replaces the default rather than adding to it. The total therefore describes the mailable audience, not everyone matching the other filters — say so when you report it.

InputTypeMeaning
qstringFree text over name, headline, job title and company. A short query needs every word; a longer one needs most of them, so a five-word phrase behaves as a keyword search rather than an exact match. Prefer the structured filters below.
profileKeywordsstring[]The same as keywords — the person’s own profile text; kept under this name for clients that adopted it.
excludeProfileKeywordsstring[]Profile keywords to exclude.
titlestring[]Job title keywords, e.g. ["Head of Sales","VP Sales"]. Wrap a value in [brackets] for an exact match.
excludeTitlestring[]Job titles to exclude, e.g. ["assistant","intern"].
seniorityenum[]LeadOcean seniority band (finer than jobLevel).
jobLevelenum[]Seniority band of the current role.
jobFunctionenum[]Department of the current role.
countryenum[]Where the person is, ISO 3166-1 alpha-2, e.g. ["US","DE"].
continentenum[]Continent the person is in.
salesRegionenum[]Commercial region the person is in.
citystring[]City keywords for the person.
excludeCitystring[]Cities to exclude.
educationstring[]School, degree or year phrases, e.g. ["Stanford"].
minConnectionsintMinimum LinkedIn connections on the person's profile, 0–500.
domainstring[]Company website domains, e.g. ["stripe.com"].
companyNamestring[]Company name keywords.
excludeCompanyNamestring[]Company name keywords to exclude.
companyLinkedinstring[]Company LinkedIn URLs, e.g. ["https://www.linkedin.com/company/stripe"].
industryenum[]Company industry — 534 values; resolve with leadocean_list_enum_values before guessing.
excludeIndustryenum[]Industries to exclude; same 534 values.
companyTypeenum[]Legal type of the company.
employeeRangeenum[]Headcount bracket — cheaper and broader than minEmployees/maxEmployees.
minEmployeesintCompany headcount, lower bound — only records whose value we hold; one with no figure on file is never returned.
maxEmployeesintCompany headcount, upper bound — only records whose value we hold; one with no figure on file is never returned.
minRevenueintAnnual revenue in USD — only records whose value we hold; one with no figure on file is never returned.
maxRevenueintAnnual revenue ceiling in USD — only records whose value we hold; one with no figure on file is never returned.
minFoundedintYear the company was founded — only records whose value we hold; one with no figure on file is never returned.
maxFoundedintLatest year the company was founded — only records whose value we hold; one with no figure on file is never returned.
minFollowersintMinimum company LinkedIn followers — 0 means no minimum; any value of 1 or more matches only records whose figure we hold.
fundingTypeenum[]Type of the last funding round.
minFundingintTotal funding raised, USD — only records whose value we hold; one with no figure on file is never returned.
maxFundingintTotal funding raised, USD ceiling — only records whose value we hold; one with no figure on file is never returned.
minLastFundingYearintFunded no earlier than this year — only records whose value we hold; one with no figure on file is never returned.
maxLastFundingYearintFunded no later than this year — only records whose value we hold; one with no figure on file is never returned.
investorsstring[]Lead investor name keywords, e.g. ["Sequoia"].
naicsstring[]NAICS industry codes, e.g. ["5415"].
sicstring[]SIC industry codes.
keywordsstring[]Keywords in the person’s own profile: headline, summary, skills and job descriptions — the PERSON’s text, not the employer’s (for the company’s text search companies, or filter people by industry / companyName). Each value is a phrase whose words must all appear; several values OR together.
excludeKeywordsstring[]Profile keywords to exclude.
hqCountryenum[]Company headquarters country, ISO 3166-1 alpha-2.
hqCitystring[]Company headquarters city keywords.
hqStatestring[]Company headquarters state or region.
hqContinentenum[]Continent of the company headquarters.
hqSalesRegionenum[]Commercial region of the company headquarters.
technologiesstring[]Technologies detected on the company website (LeadOcean data only).
technologyCategoriesenum[]What the detected technology is for, e.g. Analytics or CDN, rather than its name (own data only; covers the ~7.8M crawled companies).
emailStatusenum[]Email deliverability (LeadOcean data only).
emailTypeenum[]Work or personal email (LeadOcean data only). Pair with emailStatus to ask for a deliverable WORK address.
hasEmailbooleantrue = only people with a known email, false = only those without (LeadOcean data only).
hasPhonebooleanOnly people with, or without, a known phone number (own data only).
reachableenumHolding an email OR a phone — `strict` additionally requires the email to be verified, catch_all_valid or catch_all.
facetsbooleanBreak the total down by seniority, country, industry and company size. On by default. The breakdown is the slow part of this call — four aggregations over the matched set — so pass false when you only want the number and it returns in well under a second.

leadocean_get_lead · Get lead (enrich one person) · 1 record

Enrich ONE specific person. Pass a LinkedIn profile URL (preferred), a work email, or — when the person came from leadocean_search_leads — the person_id that row carries at meta.source_ids.person_id, which is the only identifier that works for the roughly one person in five who has no LinkedIn URL. The same row carries meta.source_ids.person_group_id: person_id names a RECORD, person_group_id names the PERSON as far as our deduplication knows — two records with the same person_group_id are one human, whichever key you reached them by. Compare it; do not look it up. Returns the full leadocean.person.v1 record: profile_data (identity, headline, summary, location, picture, languages, tags), contact_data (current experiences with company details, still-at-company status, has_email / email_status / email_type flags; email addresses and phones ONLY when reveal_email=true), resume_data — EMPTY from the current source: the enrichment store carries contact points and the current role, not career history, so experiences/educations/certifications/awards/skills come back as {} and a caller should not wait on them. Not for discovery — use leadocean_search_leads to find people first. Counts as 1 record, with or without reveal_email.

InputTypeMeaning
linkedin_urlurlLinkedIn profile URL, e.g. https://www.linkedin.com/in/jane-doe (preferred key).
emailemailWork email address — used when no LinkedIn URL is known.
phonestringPhone number in any common format — the reverse lookup: who is this number. The REST API has always accepted it; this tool used to strip it and then answer "phone is required", which is the opposite of the truth.
person_idstringThe id a search row already handed you: meta.source_ids.person_id on any leadocean_search_leads result. Pass it straight back to enrich that exact person — this is the tool to reach for after a search, because it saves carrying an identifier between the two calls. It is a translation rather than a fourth key: the person is looked up by id and the enrichment then runs on the identifier their own record holds, so it is the same record, the same one-record price, the same cached answer and the same meta.key_hash as passing that identifier yourself. Reach for it in particular when a search row has no profile_url — about a fifth of the people search can find have no LinkedIn URL, and search publishes email FLAGS and never an address, so for those people this is the only identifier you can hold. Digits only, as returned. Two distinct 404s: nobody carries that id (a typo, or a row from an older index), or the person exists and we hold no identifier we can enrich by for them — the second says so plainly, is not your mistake, and will not change on a retry.
reveal_emailbooleantrue = include every contact point we hold — email addresses AND phone numbers — in contact_data. Despite the name it governs BOTH; for phones alone, leadocean_find_phone is the tool to reach for. Costs no extra credit: one enrichment is one record either way.

leadocean_find_phone · Find phone number · 1 record

Get the PHONE NUMBERS we hold for ONE person. Pass a LinkedIn profile URL (preferred), a work email, a phone number you already have, or the person_id a leadocean_search_leads row carries at meta.source_ids.person_id. Returns has_phone plus every number, each with its type (mobile/direct/office) and priority — best first. has_phone: false means we genuinely hold none, not that the lookup failed. Pair it with leadocean_search_leads: search with hasPhone=true (or reachable) to find people who HAVE a number, which costs nothing extra, then call this for the ones you want. Counts as 1 record, the same as an enrichment — this is the same lookup under a name you can find, so calling it instead of leadocean_get_lead costs nothing more. Not for discovery: it answers about a person you can already name.

InputTypeMeaning
linkedin_urlurlLinkedIn profile URL, e.g. https://www.linkedin.com/in/jane-doe (preferred key).
emailemailWork email address — used when no LinkedIn URL is known.
phonestringA number you already hold, to find the rest we have for that person.
person_idstringThe id a search row already handed you: meta.source_ids.person_id on any leadocean_search_leads result. Search with hasPhone=true to find people who HAVE a number, then pass each row's person_id here — nothing to carry between the two calls, and it works for the rows with no profile_url, which is about one person in five. It is a translation rather than a fourth key: the person is looked up by id and the lookup then runs on the identifier their own record holds, so it is the same numbers, the same one-record price and the same meta.key_hash as passing that identifier yourself. Digits only, as returned. Two distinct 404s: nobody carries that id, or the person exists and we hold no identifier we can enrich by for them — the second says so plainly and will not change on a retry.

leadocean_search_companies · Search companies · 1 record

Find companies rather than people: industry, headcount, revenue, funding, technologies, headquarters. Returns leadocean.company.v1 records. Use it to build an account list first, then pass a domain to leadocean_search_leads to find the people inside. Each company returned counts one record. Paginate with `cursor` (meta.nextCursor). Paging is capped: one search pages through 10,000 rows by default, and on the page that reaches the cap meta.nextCursor is null and meta.depthCapped is true. That walk is over — retrying the same query returns no further cursors, and paging harder is never the fix. Narrow the filters and run several smaller searches instead (split by country, then industry, then headcount band, then title). The figure is per account: an account with a genuine large export to run can have it raised, so tell the user to ask support rather than looping around it. It counts rows PAGED THROUGH and is not the monthly records allowance, which is a separate limit and unaffected. The cursor itself is opaque and signed: pass back exactly the string meta.nextCursor gave you, unchanged. A cursor that has been edited, truncated or built by hand, or one minted for a different search, is refused with 400 "Invalid cursor"; so is any cursor issued before 2026-09-19, in which case start that query again from the first page. Do not store a cursor for later — it is a position in one walk, not a handle on a result set.

InputTypeMeaning
qstringFree text over name, headline, job title and company. A short query needs every word; a longer one needs most of them, so a five-word phrase behaves as a keyword search rather than an exact match. Prefer the structured filters below.
namestring[]Company name keywords.
excludeNamestring[]Company name keywords to exclude.
domainstring[]Company website domains, e.g. ["stripe.com"].
linkedinstring[]Company LinkedIn URLs — resolved through the people we hold at the company (most real companies); a URL nobody works at is a 404 pointing at GET /v1/companies/enrich?linkedin_url=…, which always works.
industryenum[]Company industry — 534 values; resolve with leadocean_list_enum_values before guessing.
excludeIndustryenum[]Industries to exclude; same 534 values.
companyTypeenum[]Legal type of the company.
employeeRangeenum[]Headcount bracket — cheaper and broader than minEmployees/maxEmployees.
minEmployeesintCompany headcount, lower bound — only records whose value we hold; one with no figure on file is never returned.
maxEmployeesintCompany headcount, upper bound — only records whose value we hold; one with no figure on file is never returned.
minRevenueintAnnual revenue floor in USD — only records whose value we hold; one with no figure on file is never returned.
maxRevenueintAnnual revenue ceiling in USD — only records whose value we hold; one with no figure on file is never returned.
minFollowersintMinimum company LinkedIn followers — 0 means no minimum; any value of 1 or more matches only records whose figure we hold.
minFoundedintEarliest year the company was founded — only records whose value we hold; one with no figure on file is never returned.
maxFoundedintLatest year the company was founded — only records whose value we hold; one with no figure on file is never returned.
fundingTypeenum[]Type of the most recent funding round.
minFundingintTotal funding raised, USD floor — only records whose value we hold; one with no figure on file is never returned.
maxFundingintTotal funding raised, USD ceiling — only records whose value we hold; one with no figure on file is never returned.
minLastFundingYearintFunded no earlier than this year — only records whose value we hold; one with no figure on file is never returned.
maxLastFundingYearintFunded no later than this year — only records whose value we hold; one with no figure on file is never returned.
investorsstring[]Lead investor name keywords, e.g. ["Sequoia"].
naicsstring[]NAICS industry codes, e.g. ["5415"].
sicstring[]SIC industry codes.
keywordsstring[]Keywords across company description, specialties and categories.
excludeKeywordsstring[]Company keywords to exclude.
hqCountryenum[]Company headquarters country, ISO 3166-1 alpha-2.
hqCitystring[]Company headquarters city keywords.
hqStatestring[]Company headquarters state or region.
hqContinentenum[]Continent of the company headquarters.
hqSalesRegionenum[]Commercial region of the company headquarters.
technologiesstring[]Technologies detected on the company website (LeadOcean data only).
technologyCategoriesenum[]What the detected technology is for, e.g. Analytics or CDN, rather than its name (own data only; covers the ~7.8M crawled companies).
cursorstringOpaque page token from meta.nextCursor — pass it back exactly as returned. It is signed: an edited, truncated or hand-built cursor, or one from a different search, is refused with 400 "Invalid cursor". Null nextCursor means no more pages, either because the results ran out or because the search hit its depth cap (meta.depthCapped).
limitintCompanies per page, 1–100 (default 25).

leadocean_get_company · Get company · 1 record

Look up ONE company by website domain (preferred) or LinkedIn company URL. Returns leadocean.company.v1: company_data (name, description, industry, headcount and size code in company_employees, LinkedIn follower count in company_linkedin_followers, headquarters address, founded year, website, social links), company_detected_technologies, and company_metrics (completion_score, marketability_score). Use it to qualify an account, or to get the domain before searching its people with leadocean_search_leads(domain=…). Counts as 1 record.

InputTypeMeaning
linkedin_urlurlLinkedIn company page, e.g. https://www.linkedin.com/company/stripe
domainstringWebsite domain, e.g. "stripe.com" (preferred key).

leadocean_export_leads · Start a bulk CSV export · 1 record

Start a bulk export of people as a plain CSV file — ASYNCHRONOUS. This tool returns at once with an export id and status "queued"; the file is NOT ready. Poll leadocean_get_export every pollAfter seconds until status is "done", then hand the user the download link it returns (do not try to read the CSV through a tool). BILLING: up to `limit` records are reserved on the account the moment this is accepted, and each written row is charged like a search result; a column outside the search row adds one enrichment per row. Refused up front, never silently capped: 400 when `limit` exceeds 50,000 or a filter cannot be applied, 429 export_limit_daily / export_limit_monthly with `remaining` and `resetsAt`, 402 when the account has fewer records left than the export needs. One export runs per account at a time; further ones queue. Always call leadocean_count_leads first and confirm the size with the user.

InputTypeMeaning
qstringFree text over name, headline, job title and company. A short query needs every word; a longer one needs most of them, so a five-word phrase behaves as a keyword search rather than an exact match. Prefer the structured filters below.
profileKeywordsstring[]The same as keywords — the person’s own profile text; kept under this name for clients that adopted it.
excludeProfileKeywordsstring[]Profile keywords to exclude.
titlestring[]Job title keywords, e.g. ["Head of Sales","VP Sales"]. Wrap a value in [brackets] for an exact match.
excludeTitlestring[]Job titles to exclude, e.g. ["assistant","intern"].
seniorityenum[]LeadOcean seniority band (finer than jobLevel).
jobLevelenum[]Seniority band of the current role.
jobFunctionenum[]Department of the current role.
countryenum[]Where the person is, ISO 3166-1 alpha-2, e.g. ["US","DE"].
continentenum[]Continent the person is in.
salesRegionenum[]Commercial region the person is in.
citystring[]City keywords for the person.
excludeCitystring[]Cities to exclude.
educationstring[]School, degree or year phrases, e.g. ["Stanford"].
minConnectionsintMinimum LinkedIn connections on the person's profile, 0–500.
domainstring[]Company website domains, e.g. ["stripe.com"].
companyNamestring[]Company name keywords.
excludeCompanyNamestring[]Company name keywords to exclude.
companyLinkedinstring[]Company LinkedIn URLs, e.g. ["https://www.linkedin.com/company/stripe"].
industryenum[]Company industry — 534 values; resolve with leadocean_list_enum_values before guessing.
excludeIndustryenum[]Industries to exclude; same 534 values.
companyTypeenum[]Legal type of the company.
employeeRangeenum[]Headcount bracket — cheaper and broader than minEmployees/maxEmployees.
minEmployeesintCompany headcount, lower bound — only records whose value we hold; one with no figure on file is never returned.
maxEmployeesintCompany headcount, upper bound — only records whose value we hold; one with no figure on file is never returned.
minRevenueintAnnual revenue in USD — only records whose value we hold; one with no figure on file is never returned.
maxRevenueintAnnual revenue ceiling in USD — only records whose value we hold; one with no figure on file is never returned.
minFoundedintYear the company was founded — only records whose value we hold; one with no figure on file is never returned.
maxFoundedintLatest year the company was founded — only records whose value we hold; one with no figure on file is never returned.
minFollowersintMinimum company LinkedIn followers — 0 means no minimum; any value of 1 or more matches only records whose figure we hold.
fundingTypeenum[]Type of the last funding round.
minFundingintTotal funding raised, USD — only records whose value we hold; one with no figure on file is never returned.
maxFundingintTotal funding raised, USD ceiling — only records whose value we hold; one with no figure on file is never returned.
minLastFundingYearintFunded no earlier than this year — only records whose value we hold; one with no figure on file is never returned.
maxLastFundingYearintFunded no later than this year — only records whose value we hold; one with no figure on file is never returned.
investorsstring[]Lead investor name keywords, e.g. ["Sequoia"].
naicsstring[]NAICS industry codes, e.g. ["5415"].
sicstring[]SIC industry codes.
keywordsstring[]Keywords in the person’s own profile: headline, summary, skills and job descriptions — the PERSON’s text, not the employer’s (for the company’s text search companies, or filter people by industry / companyName). Each value is a phrase whose words must all appear; several values OR together.
excludeKeywordsstring[]Profile keywords to exclude.
hqCountryenum[]Company headquarters country, ISO 3166-1 alpha-2.
hqCitystring[]Company headquarters city keywords.
hqStatestring[]Company headquarters state or region.
hqContinentenum[]Continent of the company headquarters.
hqSalesRegionenum[]Commercial region of the company headquarters.
technologiesstring[]Technologies detected on the company website (LeadOcean data only).
technologyCategoriesenum[]What the detected technology is for, e.g. Analytics or CDN, rather than its name (own data only; covers the ~7.8M crawled companies).
emailStatusenum[]Email deliverability (LeadOcean data only).
emailTypeenum[]Work or personal email (LeadOcean data only). Pair with emailStatus to ask for a deliverable WORK address.
hasEmailbooleantrue = only people with a known email, false = only those without (LeadOcean data only).
hasPhonebooleanOnly people with, or without, a known phone number (own data only).
reachableenumHolding an email OR a phone — `strict` additionally requires the email to be verified, catch_all_valid or catch_all.
limitintRows to export — the account is charged up to this many records (times 2 when a column needs an enrichment). At most 50,000 per export; 500,000 per day and 10,000,000 per period per account. Call leadocean_count_leads first to size it.
columnsstring[]Column ids from GET /v1/exports/columns (the catalogue), in order. Omit to use a preset. Every row costs one record whatever the columns; email_N_* columns need reveal email, phone_N_* need email_phone (enrich scope).
presetstringA named column set instead of listing columns. full (default, 45 columns): identity, profile, address, contact flags, emails 1–3, phones 1–2, current role, education, skills — needs the enrich scope. search (27 columns): what the search row carries, no contact points. One record per row either way.
revealstringWhether contact points are exported. Derived from the columns when omitted. Needs a key with the enrich scope.
namestringA label for the export, shown in the list and the ready email.

leadocean_get_export · Get an export (poll) · free

Status and progress of one export. FREE. While queued or running, wait pollAfter seconds and call again. When done, downloadUrl is a signed link to the plain .csv that opens in a browser WITHOUT an API key — the same link as the ready email — valid until downloadExpiresAt (24 hours, never past the file’s 7 days), and downloadNote says so in a sentence you can pass on. An expired link is renewed by calling this tool again: a new 24-hour link, free, nothing rebuilt, for as long as the file is kept. Give it to the user rather than fetching it here. failed and cancelled exports keep what they wrote: rows written are billed and the partial file is downloadable.

InputTypeMeaning
idstringThe export id from leadocean_export_leads.

leadocean_get_account · Account status · free

Everything about the account this key spends, in one FREE call: plan and whether it is fair use, records used / remaining / when they reset and what happens past the ceiling (throttled or refused), an active grant, the subscription state (no invoices or card details), today’s and this period’s export rows against their ceilings, and the rate. Call this before a large job, or after a 402 or 429, instead of guessing.

leadocean_list_exports · List exports · free

The account’s newest exports (up to 100), 90 days of history. FREE. The REST list (GET /v1/exports) pages further with a cursor.

InputTypeMeaning
statusstringOnly exports in this state.
limitintHow many of the newest to return, default 25.

What each tool costs is the same as the REST call behind it — see records, limits and errors. So are its limits: a tool that pages with a cursor stops at the same depth cap as the endpoint underneath it.

llms.txt

The whole API is published as plain Markdown for models: llms.txt is the index and llms-full.txt has every endpoint, parameter, enum value, schema field group, error and tool. Both are generated from the running API, so they never drift. Paste the URL into Claude, add it to Cursor as a doc, or fetch it in your own system prompt.

Ask your assistant: “Read https://api.leadocean.io/llms-full.txt and use it as the reference for the LeadOcean API.”