Enrichment API

Company Funding API

POST /v1/companies/enrich. One domain in, total raised, last round and lead investors out. 1 record per company found, a 404 is free.

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

POST /v1/companies/enrich takes one domain or LinkedIn company URL and returns the company record, including its funding block. It costs 1 record per company found. A 404 costs nothing.

Funding is not a separate endpoint. It is the company_data.company_funding object inside leadocean.company.v1. This page is the developer reference. For what the data is and where it comes from, read Company funding data. The same lookup is the leadocean_get_company tool over MCP.

Quick start (curl)

Create a free account, copy a key with the enrich scope and export it as LEADOCEAN_API_KEY.

bash
curl -s -X POST "https://api.leadocean.io/v1/companies/enrich" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"domain":"acme.com"}'

The endpoint also answers GET with query parameters:

bash
curl -s -G "https://api.leadocean.io/v1/companies/enrich" \
  --data-urlencode "linkedin_url=https://www.linkedin.com/company/acme" \
  -H "x-api-key: $LEADOCEAN_API_KEY"

Node.js (fetch)

js
const res = await fetch("https://api.leadocean.io/v1/companies/enrich", {
  method: "POST",
  headers: {
    "x-api-key": process.env.LEADOCEAN_API_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({ domain: "acme.com" }),
});

if (res.status === 404) {
  console.log("Company not in our data. Not billed.");
} else if (!res.ok) {
  throw new Error(`${res.status} ${(await res.json()).error?.message}`);
} else {
  const { data } = await res.json();
  const funding = data.company_data?.company_funding;
  console.log(funding ?? "Company found, no funding block");
}

Python (requests)

python
import os
import requests

r = requests.post(
    "https://api.leadocean.io/v1/companies/enrich",
    json={"domain": "acme.com"},
    headers={"x-api-key": os.environ["LEADOCEAN_API_KEY"]},
    timeout=10,
)

if r.status_code == 404:
    print("Company not in our data. Not billed.")
else:
    r.raise_for_status()
    company = r.json()["data"]["company_data"]
    print(company.get("company_funding") or "Company found, no funding block")

Which call to use

Use enrich when you already hold the domain. You get the funding block plus headcount and firmographics in one record. Use search when you only know the stage you want.

Enrich is a lookup, not an alert. The docs show no way to be told when a company raises, and the record carries only the last round, not a round-by-round history. Re-run your list on a schedule if you need to catch new rounds.

Request

Send domain or linkedin_url. The key needs the enrich scope. There is no lookup by company name.

ParameterTypeRequiredMeaning
domainstringOne of the twoWebsite domain, for example acme.com. Preferred.
linkedin_urlstring (URL)One of the twoLinkedIn company page URL.

POST takes these as a JSON body. GET takes them as query parameters. POST /v1/companies/enrich is an older alias, so use the path above.

Response

Response shape from the API reference. Every value below is a placeholder.

json
{
  "success": true,
  "data": {
    "company_data": {
      "company_name": "Acme",
      "company_domain": "acme.com",
      "company_funding": {
        "total_raised_usd": 42000000,
        "last_round_type": "Series B",
        "last_round_date": "2025-06-12",
        "last_round_year": 2025,
        "lead_investors": ["Acme Ventures"]
      },
      "company_employees": {
        "number_of_employees": 240,
        "number_of_employees_code": "201-500"
      }
    },
    "company_metrics": { "completion_score": 94, "marketability_score": 81 },
    "meta": { "schema": "leadocean.company.v1", "fetched_at": "2026-09-01T00:00:00Z" }
  },
  "meta": { "credits": 1, "source": "leadocean" }
}
FieldMeaning
company_funding.total_raised_usdTotal raised, in USD.
company_funding.last_round_typeType of the latest round, such as Series B.
company_funding.last_round_dateDate of that round.
company_funding.last_round_yearYear of that round.
company_funding.lead_investors[]Lead investor names.
meta.creditsRecords counted for this call.

The docs say funding is held for a small fraction of companies and absent is the normal case, not an error. Unknown values are null, never guessed. Read the block defensively, as in the code above.

Each record also carries meta.fetched_at, and the dataset is refreshed monthly. Check that date before you treat a round as current.

Errors

Every failure is { "success": false, "error": { "message": "...", "details": ... } }. Status codes are from the limits docs, September 2026.

StatusMeaningWhat to do
400Validation failed. details names the wrong fields.Send domain or linkedin_url. Not billed.
401Missing, wrong or revoked key.Check the x-api-key header.
402Free plan: the 1,000 records are spent. They do not reset.Upgrade. Not billed.
403The key lacks the enrich scope, or the account is suspended.Create a key with the scope.
404Not in our data.Stop. It costs nothing. Try the other identifier.
429Over 100 requests a second, or 1 a minute on a paid account past its records.Wait for Retry-After, then retry. Not billed.
503The store behind the lookup is unreachable (code: no_source).Retry with backoff. Never billed.

Rate limits and cost

One company found is 1 record, whether you send a domain or a LinkedIn URL. A 200 with an empty funding block still costs 1 record. A 404, 429, 402 or 503 costs nothing.

The limit is 100 requests per second per key, on every plan. Free is 1,000 records, one-off, no card. Pro is $499 a month, flat, with no per-record price inside fair use. See pricing.

To list companies by funding stage instead of looking one up, use POST /v1/companies/search with fundingType, minLastFundingYear or investors. Size it first with count=true and limit=1, which is free. Do not trust that total when a funding filter is on it, because the count can come back unsupported.

Bulk

Funding is not an export column, so POST /v1/exports cannot return it. The export columns cover each person's current company: current_company_domain, current_company_name, current_company_employees and so on.

Use an export to build the list, then enrich the domains. Contact columns are numbered: email_N_address and email_N_status come back as email_1_address, email_1_status, email_2_address and so on. caps sets how many (default 3 emails).

bash
curl -X POST https://api.leadocean.io/v1/exports \
  -H "x-api-key: $LEADOCEAN_API_KEY" -H "content-type: application/json" \
  -d '{
    "name": "VPs at Series B companies",
    "filters": { "jobLevel": ["VP"], "fundingType": ["Series B"] },
    "limit": 5000,
    "columns": ["person_id", "profile_full_name", "current_company_domain", "email_N_address", "email_N_status"],
    "caps": { "emails": 1 }
  }'

The reply is a 202 with a job id. Poll GET /v1/exports/{id}, then fetch /v1/exports/{id}/download. One export row is 1 record. Then call the enrich endpoint once per unique current_company_domain.

FAQ

Does a company with no funding data cost a record?

Yes, if we hold the company and return it. You pay for the record received, and company_funding may be missing or null. A 404 costs nothing.

Can I look up funding by company name?

No. Send a domain or a LinkedIn company URL. With only a name, search companies first, then enrich the domain you get back.

Can an agent call it without an API key?

Yes. The MCP server at https://api.leadocean.io/mcp signs in with OAuth 2.1, so no key is pasted. The tool is leadocean_get_company, 1 record. See company enrichment over the API and the company data API comparison.

Get your company funding API key free

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

Get your free API key →