You get a script that finds Close contacts nobody has enriched, sends each one to LeadOcean, and writes the work email, phone and job title back. Close has no LeadOcean app, so the recipe uses two plain HTTP APIs: https://api.close.com/api/v1 and https://api.leadocean.io. Run it from cron, a CI job or any scheduler you already own. The screenshots below show the recipe running.
How it works
The script makes three calls per contact: find, enrich, update. A custom field on the contact records when it was enriched, so the next run skips it.
- Create a LeadOcean key. Sign up at app.leadocean.io/register. The free plan needs no card and gives 1,000 records.
- Create a Close API key. In Close go to Settings, Developer, API Keys (Close docs, September 2026). The key is scoped to one user and organization.
- Add a contact custom field. Create a
datetimefield named "LeadOcean enriched at" withPOST /custom_field/contact/(Close docs, September 2026). Note itscf_id. - Find contacts to enrich. Call
POST /api/v1/data/search/with anobject_typeof contact. The Advanced Filtering API returns contact ids and a cursor (Close docs, September 2026). Skip any contact whose stamp field is set. - Enrich each contact. Send the contact's email, or its LinkedIn URL when it has no email, to
POST /v1/people/enrich. Send one identifier only. - Write back and stamp.
PUT /api/v1/contact/{id}/with the new email, phone and title, plus the stamp field (Close docs, September 2026). - Schedule it. Run the script hourly or nightly. For near-live enrichment, subscribe a webhook to the Close
contactcreatedevent. Run the same enrich step from your endpoint (Close docs, September 2026).
For a one-off list, use the Exports page in the LeadOcean app. It has a filter builder, column picker and price preview, and gives you a CSV to import into Close.
Configuration
The Close API uses HTTP Basic auth: the API key is the username and the password is empty (Close docs, September 2026). Keep both keys in environment variables.
Enrich one contact:
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@acme.com","reveal_email":true}'Write the result back to Close. Send the complete, merged email and phone lists, not a single new entry. Close's update docs do not say whether a list is merged or replaced, so sending the full list is the safe choice.
curl -X PUT "https://api.close.com/api/v1/contact/cont_ACME123/" \
-u "$CLOSE_API_KEY:" \
-H "content-type: application/json" \
-d '{
"title": "VP Sales",
"emails": [
{"email": "jane@acme.com", "type": "office"}
],
"phones": [
{"phone": "+14155550133", "type": "mobile"}
],
"custom.cf_YOUR_FIELD_ID": "2026-10-21T09:00:00+00:00"
}'Send exactly one identifier per LeadOcean call. Two identifiers return a 400 (LeadOcean docs, September 2026). reveal_email costs no extra record, and phones only come back when it is true. Close expects phones in E.164 format (Close docs, September 2026), so normalise before you write.
Field mapping
The enrich response is one leadocean.person.v1 object. Contact points sit under contact_data (LeadOcean docs, September 2026).
| LeadOcean field | Close field | Note |
|---|---|---|
contact_data.contact_emails[].email | emails[].email | Take addresses whose status is verified or catch_all_valid. Drop invalid, spam_trap, abuse and disposable. |
contact_data.contact_emails[].type | emails[].type | LeadOcean uses work, work_other and personal. Close takes its own labels such as office. Map work to office. Skip work_other: it is usually a past employer. |
contact_data.contact_phones[].phone | phones[].phone | Only returned with reveal_email true. Convert to E.164. |
contact_data.contact_current_experiences[].job_title | title | Current role only. Overwrite only when the Close title is empty. |
profile_data.profile_url | urls[].url | The LinkedIn profile. Add it so later runs can use it as the identifier. |
| (the run time) | custom.cf_... | Your "LeadOcean enriched at" stamp. |
Three dedupe rules keep the CRM clean:
- Stamp first. Select only contacts where the stamp field is empty. A rerun after a crash then costs nothing for contacts already done.
- Merge, do not replace. Read the contact's current
emailsandphones, add what LeadOcean found, drop exact duplicates, and send the merged list. - Gate on status. An address that fails the
statuscheck never reaches Close. LeadOcean gives no refund for bounces, so reademail_statusbefore you send (LeadOcean docs, September 2026).
A person LeadOcean holds nothing for is a 404 and costs nothing. Stamp those contacts anyway, with a note field if you want, so the script does not retry them every night.
Cost at 10,000 rows
10,000 contacts cost $97 on LeadOcean Solo. Close's built-in Enrichment would cost about $750 for one field, on top of your CRM plan.
| LeadOcean + script | Close built-in Enrichment | |
|---|---|---|
| Unit | One record per person, returns email, phone and title together | One action per field per record, 6 AI credits each |
| 10,000 records | No per-record price. Solo covers 10k enrichments every 5 hours | 60,000 credits for one field, 180,000 for three |
| Monthly cost | Solo $97, or Agency $497 for a team | $750 for 72,000 credits (one field), $2,000 for 200,000 credits (three fields) |
| Free option | 1,000 records, one-off, no card | 500 to 2,000 credits per user, by plan |
The Close side comes from Close's own rules. An enrichment action is one field on one record, and it uses 6 credits (Close help, October 2026). The AI credit tiers are $750 for 72,000 credits and $2,000 for 200,000 credits (Close help, October 2026). Included credits reduce the tier you need, for example 15,000 on Growth at ten users. Credits reset monthly and do not roll over.
The two products do different jobs. Close Enrichment uses AI to fill custom fields from the web. LeadOcean returns emails and phones, each with a status, from its own database of 693M people. Use LeadOcean for emails and phones, and Close Enrichment for free-text fields like a company description.
The first 1,000 contacts run on LeadOcean Free. Your Close plan price is separate and unchanged. See pricing for what each LeadOcean plan includes. If you also keep contacts in other tools, the same pattern works in Retool, Notion and Folk.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 401 from LeadOcean | Key missing or wrong | Send it in the x-api-key header. |
| 400 from LeadOcean | Two identifiers sent, or an empty one | Send only email or linkedin_url. Skip contacts with neither. |
| 402 from LeadOcean | The free 1,000 records are spent | Move to Solo or Agency. Free records do not renew. |
| 404 from LeadOcean | LeadOcean holds nothing for that person | No charge. Stamp the contact and move on. |
| 429 from LeadOcean | Over the per-plan rate limit | 5 requests a second on Free, 50 on Solo, 200 on Agency. Honour Retry-After. |
| 429 from Close | Close rate limit hit | Pause for the retry-after header value. Close limits per endpoint group (Close docs, September 2026). |
| 400 from Close on PUT | Phone not in E.164, or a bad cf_ id | Normalise phones. Read your field ids from /custom_field_schema/contact/. |
| Same contact enriched twice | Stamp not written, or search ignores it | Check the PUT returned 200, then check your search excludes stamped contacts. |
FAQ
Does LeadOcean have a native Close integration?
No. Close has a public REST API and webhooks, and LeadOcean is a REST API, so a short script connects them. There is no LeadOcean listing in Close's directory.
Can I run this without writing code?
Not from LeadOcean's side alone. Close lists a Zapier integration (Close help, September 2026). The Zapier recipe on the Zapier page uses a webhook step that works the same way.
Which Close contacts should I enrich first?
Start with contacts that have a LinkedIn URL or an email but no phone. Those return the most for one record. Use the free count call on LeadOcean to size a list before you spend records.
How do I get phone numbers into Close?
Set reveal_email to true and read contact_data.contact_phones[] from the enrich response. You can also call GET /v2/people/phone, which costs one record per call, including a call that finds nothing.
Enrich your Close contacts with a free LeadOcean key.
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →