What you get
Person enrichment returns one record in the leadocean.person.v1 schema: who the person is, their current role, and how to reach them. Contact points come back only when you set reveal_email: true. A value we do not hold is null, never guessed.
| Field | What it is | Example |
|---|---|---|
profile_data.profile_full_name | Name | "Jane Doe" |
profile_data.profile_headline | Headline | "Head of Sales at Acme" |
profile_data.profile_url | LinkedIn profile URL | "linkedin.com/in/jane-doe" |
contact_data.has_email | Whether we hold an address | true |
contact_data.has_phone | Whether we hold a number | true |
contact_data.email_status | Deliverability of the best address | "verified" |
contact_data.email_type | Type of the best address | "work" |
contact_data.contact_emails[] | Each address with type, status, verified_batch_date, priority, score | "jane@acme.com" |
contact_data.contact_phones[] | Each number with type, ddi, dnc, carrier, priority, score | "+1 415 555 0133" |
contact_data.contact_current_experiences[] | Current role: company name, domain, job title | "Acme", "acme.com" |
resume_data | Experiences, education, skills (see limits below) | {} |
meta | key_hash, source, schema, credits | "leadocean.person.v1" |
has_email and has_phone answer whether or not you reveal. That lets you check a person is worth a record before you ask for the address.
What you send
| Input | Required | Note |
|---|---|---|
linkedin_url | One of four | LinkedIn profile URL. The unambiguous key. |
email | One of four | Work email. Use it to find the person behind an address. |
phone | One of four | A number in any common format. Reverse lookup: who is this. |
person_id | One of four | The id on a people-search row at meta.source_ids.person_id. Reaches the person with no LinkedIn URL. |
reveal_email | No | Boolean, default false. True returns every email and phone we hold, at no extra record. |
Send exactly one identifier. Two is a 400. There is no lookup by name and company. Search by domain first, then enrich by person_id.
Three ways to run it
In the app
Yes, in bulk. The Exports page at app.leadocean.io builds a people list from filters, and its column picker includes the enrich fields: email_N_address, email_N_status, phone_N_number, current_job_title and more. It shows the record price before you start and gives you a CSV. For one named person, use the API or an agent.
With the API
curl -X POST "https://api.leadocean.io/v1/people/enrich" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "content-type: application/json" \
-d '{"linkedin_url":"https://www.linkedin.com/in/jane-doe","reveal_email":true}'A hit returns success: true, the data object above and meta.credits: 1. GET works too, with the same fields as query parameters.
The old POST /v1/people/enrich still answers but is deprecated.
From an AI agent
The MCP tool is leadocean_get_lead. It takes the same four identifiers. Try: "Enrich linkedin.com/in/jane-doe and give me the work email, its status and her current title." Setup is in Enrich Person over MCP. The packaged steps are in the Enrich Person skill. To push results into a CRM, see the Pipedrive enrichment recipe.
What it costs
One person found is 1 record, with or without reveal_email. A 404, meaning we hold nothing for that person, costs nothing. Rejected requests (429, 402, 503) are never metered. Over MCP, a leadocean_get_lead that finds nobody is free too.
Free gives you 1,000 records, one-off, no card. Pro is $499 a month, flat, with no per-record price, inside fair use. See pricing.
Worked example: you enrich 10,000 people and 7,000 are found. That is 7,000 records, and the 3,000 misses cost nothing. Free covers the first 1,000 once. On Pro the month is $499 whatever the count.
Coverage
LeadOcean holds 693M people. Of those, 366M have an email and 166M have a phone (measured 2026-09-23). Roughly one person in five has no LinkedIn URL, so about a fifth of the database can only be reached by person_id. The dataset is refreshed monthly, and each record carries its own fetched_at date.
Accuracy and limits
- Read
email_statusbefore you send.verifiedandcatch_all_validare the ones to send to.invalid,spam_trap,abuseanddisposableare drops.risky,roleandderivedare your call.untestedis not a negative signal. - Read
email_typetoo.workis the current employer.work_otheris usually a former one and the likeliest to bounce. - No refund for bounces. Check the status first.
- Do-not-call is not answered.
dncis published but not populated. Null means unknown, never safe to call. Run your own check. - Dates are batch dates.
verified_batch_dateis the verification run, not a timestamp for that address. Null does not mean unverified. - Career history is thin. The MCP tool description says
resume_datacomes back empty from the current source. Do not build on it. - Rate limit. 100 requests per second per key, on every plan.
- Errors. 400 validation, 401 bad key, 403 missing scope, 404 not in our data, 429 too fast, 503 store unreachable and never billed.
FAQ
What do I need to enrich a person?
One of a LinkedIn profile URL, a work email, a phone number or a person_id. A name and company alone does not work.
Does a failed lookup use my records?
No. A 404 costs nothing, on REST and over MCP. A search row with has_email and has_phone both false has nothing to return, so check those flags first.
Does revealing the email cost extra?
No. The call is 1 record either way. Set reveal_email whenever you want the addresses and numbers.
Can I enrich someone with no LinkedIn URL?
Yes, by person_id. Search first, then send the id from the row back. It matters because about a fifth of the people we hold have no LinkedIn URL.
Enrich your first 1,000 people free
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →