Eight small calls keep a Pipedrive pipeline clean: size, enrich a person, enrich a company, gate on email status, add a phone, reverse-check, backfill an account, and export in bulk. Each one is a LeadOcean endpoint, and the last step writes the result back to Pipedrive.
This is a recipe, not a ranking. For a ranked list of vendors, read best enrichment tools for Pipedrive.
TL;DR
- Time: about 60 minutes for a 100-person pilot, most of it spent mapping Pipedrive fields.
- Records: about 100 to 200 LeadOcean records. An enrichment that finds nothing costs nothing, and sizing is free.
- Where it stops: LeadOcean is an API and an app with an Exports page. It has no Pipedrive sync. You write the PATCH yourself, or run it from n8n or Make.
Prerequisites
- A LeadOcean key in
$LEADOCEAN_API_KEY. Sign up at app.leadocean.io/register. Free gives 1,000 records for life, no card, 5 requests a second. - A Pipedrive API token in
$PIPEDRIVE_API_TOKENand your company domain in$PIPEDRIVE_DOMAIN. - A list of Pipedrive person ids that are missing an email, a phone or a job title.
curland Python 3 withrequests.
Step 1: Size the gap before you spend anything
Tool 1 is the free count. Send count=true as a query parameter with limit 1 and nothing is billed (LeadOcean API reference, October 2026).
curl -X POST "https://api.leadocean.io/v1/people/search?count=true" \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jobLevel":["Director"],"jobFunction":["Sales & Business Development"],"country":["US"],"limit":1}'Read meta.total. It caps at 100,000. For accounts, GET /v1/companies/count sizes a company list for free and breaks it down by industry, headcount band and HQ country.
Step 2: Enrich a person by the email already in Pipedrive
Tool 2 fills the profile. Send exactly one of linkedin_url, email, phone or person_id. A person we hold nothing for is a 404 and costs nothing.
curl -X POST https://api.leadocean.io/v1/people/enrich \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"jane.doe@acme.com","reveal_email":true}'The answer holds the current role in contact_data.contact_current_experiences[]. Since October 2026 it also returns career history in resume_data: past roles, education and certifications, each when held. Past employers carry no company_id yet.
Step 3: Enrich the organization by domain
Tool 3 fixes the Pipedrive organization record. Use the domain you already store.
curl -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 response has company_data, company_detected_technologies and company_metrics. Map the fields you need into Pipedrive organization custom fields. Do not map all of them.
Step 4: Gate every email on its status
Tool 4 is a rule, not a call. Every address carries an email_status. Decide what overwrites a Pipedrive email before you write anything.
Overwrite or add: verified
Add, flag in Pipedrive: catch_all_valid, catch_all
Never write: risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, noneThere is no refund for bounced emails. Read email_status first. For a single current work address that passes the check, GET /v2/people/email/work returns one address or data: null, at one record per call.
Step 5: Fill missing phones
Tool 5 adds numbers only for persons that lack one. Check first: a search row publishes has_phone, so you know a number exists before you spend a record.
curl "https://api.leadocean.io/v2/people/phone?linkedin_url=https://www.linkedin.com/in/jane-doe-example" \
-H "x-api-key: $LEADOCEAN_API_KEY"Numbers come back best first, each with phone and type. The call costs one record, including when it finds nothing. The v2 endpoint does not publish a do-not-call flag, so its absence is not clearance. Run your own DNC check before dialing.
Step 6: Reverse-check unknown inbound contacts
Tool 6 answers "who is this?" for a person Pipedrive created from a form or an email with no name or title.
curl "https://api.leadocean.io/v2/people/reverse?email=lead@acme.com" \
-H "x-api-key: $LEADOCEAN_API_KEY"It returns the identity, not the full profile. For the full profile, call /v1/people/enrich next. Both cost one record and answer from the same cached record.
Step 7: Backfill an account with its missing contacts
Tool 7 fills a thin organization. List the people we hold at a domain, then enrich only the ones you want.
curl "https://api.leadocean.io/v1/companies/acme.com/people?limit=25" \
-H "x-api-key: $LEADOCEAN_API_KEY"This endpoint stops at 10,000 rows. When a page is capped, meta.depthCapped is true and there is no nextCursor. Narrow the filters instead of walking the index. Each returned person is one record, so keep limit low.
Step 8: Backfill in bulk with an export
Tool 8 is for thousands of rows. Bulk CSV export is not on Free. It is included on Solo ($97 a month), and Agency ($497 a month) allows 50,000 rows a file. One request takes up to 50,000 rows, and an account takes 500,000 rows a day.
curl -X POST https://api.leadocean.io/v1/exports \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"pipedrive-backfill","filters":{"jobLevel":["Director"],"country":["US"],"emailStatus":["verified"]},"limit":500,"columns":["person_id","profile_first_name","profile_last_name","current_job_title","current_company_domain","email_status","email_N_address"],"caps":{"emails":1}}'Poll GET /v1/exports/{id} until status is done, then download. The app at app.leadocean.io has an Exports page with a filter builder, a column picker and a price preview. It will not push rows into Pipedrive. You import the CSV or loop over it.
Order the eight tools for a pilot
Run them in this order: 1, 4, 2, 3, 5, 6, 7, 8. Size first, decide the status rule second, then spend records. Persons come before organizations because a fixed email often fixes the domain too.
Start with the persons that block a rep today: no email, no phone or a stale title. Pull them with a Pipedrive filter, take 100, and run steps 2, 3 and 5 on that batch. Check 20 by hand before you scale. Compare the new email and title against the person's LinkedIn page, and note the miss rate.
Keep the job idempotent. Store the LeadOcean person_id in a Pipedrive custom field on the first pass. On the next run, skip any person that already has it, so you never pay for the same person twice. A repeat lookup of a person we have already answered comes from the same cached record, but your own skip list is cheaper than relying on that.
Schedule the run weekly, not nightly. The dataset is refreshed monthly, and each record carries its own fetched_at date, so a nightly job re-reads the same answers.
Write the result back to Pipedrive
Pipedrive's v2 Persons API updates a person with PATCH /api/v2/persons/{id}. The body takes emails and phones arrays with a value and a primary flag, and the call costs 5 API tokens (Pipedrive docs, October 2026). Requests go to https://{companydomain}.pipedrive.com with the token in an x-api-token header (Pipedrive authentication, October 2026).
import os, requests
LO = {"x-api-key": os.environ["LEADOCEAN_API_KEY"]}
PD = f"https://{os.environ['PIPEDRIVE_DOMAIN']}.pipedrive.com/api/v2/persons"
PD_HEADERS = {"x-api-token": os.environ["PIPEDRIVE_API_TOKEN"]}
def enrich_and_patch(pd_id, email):
r = requests.post("https://api.leadocean.io/v1/people/enrich", headers=LO,
json={"email": email, "reveal_email": True})
if r.status_code == 404:
return "no match, no charge"
r.raise_for_status()
contact = r.json()["data"]["contact_data"]
good = [e for e in contact.get("contact_emails", []) if e.get("status") == "verified"]
body = {}
if good:
body["emails"] = [{"value": good[0]["email"], "primary": True}]
phones = contact.get("contact_phones", [])
if phones:
body["phones"] = [{"value": phones[0]["phone"], "primary": True}]
if body:
return requests.patch(f"{PD}/{pd_id}", headers=PD_HEADERS, json=body).status_code
return "nothing to write"Run it on 100 persons first and read what changed. Pipedrive keeps the old values only if you store them, so copy the existing email into a custom field before you overwrite.
What you get
Tool 1 on 2026-10-21, through the free leadocean_count_leads MCP tool, for US directors in Sales & Business Development:
{"total":322167,"totalIsExact":true,"totalAll":825690,"distinctCompanies":99327,"credits":0,
"defaults":"Counted only addresses worth sending to (emailStatus: verified or catch_all_valid or catch_all)"}That is a count of mailable people (verified, catch_all_valid or catch_all email), not a promise of 322,167 clean contacts. The unfiltered total for the same filters is 825,690.
A person enrichment returns this shape (response shape from the API reference, placeholder values):
{"success":true,
"data":{"profile_data":{},
"contact_data":{"has_email":true,"has_phone":true,"email_status":"verified",
"contact_emails":[{"email":"jane.doe@acme.com","type":"work","status":"verified"}],
"contact_phones":[{"phone":"+14155550133","type":"mobile","priority":1}]},
"resume_data":{}},
"meta":{}}Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 | Missing or wrong x-api-key | Check $LEADOCEAN_API_KEY and that the header is x-api-key. |
| 429 | Above the plan's rate limit (5 a second on Free, 200 on Agency) | Honor Retry-After. Loop with a short sleep. |
| 402 | Out of records | Free is 1,000 records for life. Move to Solo or Agency. |
| Empty results | Enum value spelled wrong, such as director for jobLevel | Enum values are exact strings. List them with leadocean_list_enum_values. |
| 404 on enrich | We hold nothing for that person | Free. Skip the row and try linkedin_url instead of email. |
| Export refused | Over 50,000 rows a request or 500,000 a day | Split the export by country or job level. |
FAQ
Is there a native LeadOcean app in the Pipedrive marketplace?
No. LeadOcean has an API, a hosted MCP server and an app with an Exports page. You write to Pipedrive through its own API, or through n8n, Make or Zapier.
How many records does a clean-up cost?
One record per person enriched, and one more per phone lookup. A 100-person pilot is about 100 to 200 records. See what data enrichment actually costs and pricing.
Can I use the same recipe for a support desk?
Yes. The enrich calls are the same. Only the write-back changes. See which enrichment tools work with Zendesk.
Does it overwrite what my reps typed?
Only if your code does. Write to empty fields by default and keep the old value in a custom field.
Fill your Pipedrive gaps with a free API key
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →