Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

Close integration

LeadOcean + Close: enrich contacts on a schedule

A short script that finds Close contacts with no enrichment stamp, calls LeadOcean, and writes the email, phone and job title back.

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

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.

  1. Create a LeadOcean key. Sign up at app.leadocean.io/register. The free plan needs no card and gives 1,000 records.
  2. 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.
  3. Add a contact custom field. Create a datetime field named "LeadOcean enriched at" with POST /custom_field/contact/ (Close docs, September 2026). Note its cf_ id.
  4. Find contacts to enrich. Call POST /api/v1/data/search/ with an object_type of contact. The Advanced Filtering API returns contact ids and a cursor (Close docs, September 2026). Skip any contact whose stamp field is set.
  5. 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.
  6. Write back and stamp. PUT /api/v1/contact/{id}/ with the new email, phone and title, plus the stamp field (Close docs, September 2026).
  7. Schedule it. Run the script hourly or nightly. For near-live enrichment, subscribe a webhook to the Close contact created event. 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:

bash
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.

bash
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 fieldClose fieldNote
contact_data.contact_emails[].emailemails[].emailTake addresses whose status is verified or catch_all_valid. Drop invalid, spam_trap, abuse and disposable.
contact_data.contact_emails[].typeemails[].typeLeadOcean 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[].phonephones[].phoneOnly returned with reveal_email true. Convert to E.164.
contact_data.contact_current_experiences[].job_titletitleCurrent role only. Overwrite only when the Close title is empty.
profile_data.profile_urlurls[].urlThe 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 emails and phones, add what LeadOcean found, drop exact duplicates, and send the merged list.
  • Gate on status. An address that fails the status check never reaches Close. LeadOcean gives no refund for bounces, so read email_status before 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 + scriptClose built-in Enrichment
UnitOne record per person, returns email, phone and title togetherOne action per field per record, 6 AI credits each
10,000 recordsNo per-record price. Solo covers 10k enrichments every 5 hours60,000 credits for one field, 180,000 for three
Monthly costSolo $97, or Agency $497 for a team$750 for 72,000 credits (one field), $2,000 for 200,000 credits (three fields)
Free option1,000 records, one-off, no card500 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

SymptomCauseFix
401 from LeadOceanKey missing or wrongSend it in the x-api-key header.
400 from LeadOceanTwo identifiers sent, or an empty oneSend only email or linkedin_url. Skip contacts with neither.
402 from LeadOceanThe free 1,000 records are spentMove to Solo or Agency. Free records do not renew.
404 from LeadOceanLeadOcean holds nothing for that personNo charge. Stamp the contact and move on.
429 from LeadOceanOver the per-plan rate limit5 requests a second on Free, 50 on Solo, 200 on Agency. Honour Retry-After.
429 from CloseClose rate limit hitPause for the retry-after header value. Close limits per endpoint group (Close docs, September 2026).
400 from Close on PUTPhone not in E.164, or a bad cf_ idNormalise phones. Read your field ids from /custom_field_schema/contact/.
Same contact enriched twiceStamp not written, or search ignores itCheck 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 →