You get a pipeline of three parts: a LeadOcean export split by email_status, a script that creates each person in Salesloft, and two cadences. Verified addresses go to your main cadence. Catch-all addresses go to a second cadence, so a risky domain cannot drag down the first. Both sides are plain REST with a key.
Split the lists because the status decides the risk. A verified address has been checked against the mailbox. A catch-all domain accepts any address, so a catch-all address may still bounce. LeadOcean marks it in email_status, and gives no refund for bounces.
Related: the LeadOcean integrations hub, the Smartlead recipe, the Reply.io recipe, the Outreach recipe and pricing.
How it works
Six steps. Salesloft adds a person to a cadence in a second call, so each lead costs two requests (source: Salesloft API reference, September 2026).
- Get both keys. Sign up at app.leadocean.io and copy a key from the API keys page. In Salesloft, open Your Applications, then API Keys, then Create New, and pick scopes.
- Size the list. A search with
count=trueandlimit=1costs nothing.meta.totalis capped at 100,000. - Export verified. POST your filters to
/v1/exportswithemailStatusset toverified. - Export catch-all. Repeat with
catch_all_validandcatch_all. Same filters, a second file. - Create two cadences in Salesloft. One for verified, one for catch-all. Copy both cadence ids.
- Push each CSV. For each row,
POST /v2/people, thenPOST /v2/cadence_membershipswith the new person id.
Keep the two lists apart all the way through: two exports, two cadences, two tags. That gives you a clean bounce report per status after the first send.
Run 20 rows first. Free has no bulk CSV export. On Free, search with POST /v1/people/search, then call POST /v1/people/enrich with reveal_email set to true for each person. Save the rows as a CSV. Check one person in Salesloft before you send the rest.
Prefer to click? The LeadOcean app has an Exports page with a filter builder, a column picker, the record price before you start and a Download button. The script below then pushes the file.
Configuration
Steps 3 and 4, the exports. Several values in one filter join with OR.
curl -X POST https://api.leadocean.io/v1/exports \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"salesloft verified","filters":{"jobLevel":["VP"],"jobFunction":["Sales & Business Development"],"country":["CA"],"emailStatus":["verified"],"emailType":["work"]},"limit":10000,"columns":["profile_first_name","profile_last_name","current_job_title","current_company_name","current_company_domain","email_N_address","email_N_status"]}'
curl -H "x-api-key: $LEADOCEAN_API_KEY" https://api.leadocean.io/v1/exports/EXPORT_ID
curl -H "x-api-key: $LEADOCEAN_API_KEY" -o verified.csv https://api.leadocean.io/v1/exports/EXPORT_ID/downloadFor the second file, set emailStatus to ["catch_all_valid","catch_all"] and save as catchall.csv. Contact columns need a key with the enrich scope.
Step 6, the push. Salesloft API keys go in a bearer header (source: Salesloft API key authentication, September 2026). The key needs people:write to create people and cadences:write to add cadence memberships (source: Salesloft API reference, October 2026).
import csv, os, sys, time, requests
BASE = "https://api.salesloft.com/v2"
HEAD = {"Authorization": f"Bearer {os.environ['SALESLOFT_API_KEY']}"}
path, cadence_id, tag = sys.argv[1], sys.argv[2], sys.argv[3]
for r in csv.DictReader(open(path)):
if not r["email_1_address"]:
continue
person = requests.post(f"{BASE}/people", headers=HEAD, json={
"email_address": r["email_1_address"],
"first_name": r["profile_first_name"],
"last_name": r["profile_last_name"],
"title": r["current_job_title"],
"person_company_name": r["current_company_name"],
"person_company_website": r["current_company_domain"],
"tags": ["leadocean", tag],
})
if person.status_code != 200:
print(person.status_code, r["email_1_address"], person.text[:200])
continue
pid = person.json()["data"]["id"]
requests.post(f"{BASE}/cadence_memberships", headers=HEAD,
params={"person_id": pid, "cadence_id": cadence_id})
time.sleep(0.2)Run it twice: python push.py verified.csv VERIFIED_CADENCE_ID verified and python push.py catchall.csv CATCHALL_CADENCE_ID catch-all. The tag carries the status into Salesloft, where you can filter on it.
Field mapping
Salesloft's person object has no email status field. Use a tag, or a custom field your team defines first (custom_fields holds team-defined fields only, source: Salesloft People create, September 2026).
| LeadOcean field | Salesloft field | Note |
|---|---|---|
email_1_address | email_address | Required lookup, or phone plus last name. |
email_1_status | tags | Write verified or catch-all as a tag. |
profile_first_name | first_name | Empty if the profile has no split name. |
profile_last_name | last_name | |
current_job_title | title | |
current_company_name | person_company_name | Set on the person, not the account. |
current_company_domain | person_company_website | Domain only. |
phone_1_number | phone | Salesloft wants digits without formatting. Add the column to the export. |
profile_url | linkedin_url | Add the column to the export. |
Column ids come from GET /v1/exports/columns, which needs no key. Salesloft says to update the linked account rather than rely on person_company_*, so link an account with account_id if you use account views.
Cost at 10,000 rows
A 10,000-row run needs LeadOcean Solo at $97 a month, because bulk CSV export is not on Free. Salesloft has no public price. Its pricing page sends you to a sales call (source: Salesloft pricing, September 2026).
| Item | Cost | Note |
|---|---|---|
| LeadOcean Free | $0 | 1,000 records for life. No bulk CSV export. Test with search. |
| LeadOcean Solo | $97 a month | Bulk CSV export included. Fair-use pace, no credits. |
| Salesloft | No public price | Sales-led. Ask Salesloft which plans include API keys. |
Salesloft's API limit is 600 cost per minute for the whole team, and each endpoint costs 1 by default (source: Salesloft rate limits, September 2026). Two calls per lead means 20,000 cost for 10,000 rows, or about 34 minutes at the limit. That sum is ours. Other integrations on the team share the same budget.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 401 from Salesloft | Missing or wrong bearer token. | Send Authorization: Bearer KEY, not x-api-key. |
| 403 from Salesloft | The key lacks people:write or cadences:write. | Edit the key under Your Applications and add the scope. |
| 422 on create person | No email_address, or phone without last_name. | Skip rows with no address, as the script does. |
| 429 from Salesloft | Over 600 cost a minute for the team. | Slow the loop, and stop other jobs on the team. |
| Person created, not in cadence | The membership call failed or the cadence is not visible to the key's user. | Check the cadence owner and that it is a team cadence. |
| 402 on LeadOcean export | Fewer records left than limit reserves. | Lower limit, or move to a paid plan. |
| 403 on LeadOcean export | Contact columns asked without the enrich scope. | Use a key with that scope, or drop the email columns. |
FAQ
Why split catch-all from verified?
A catch-all domain accepts any address, so you cannot confirm the mailbox exists. Separate cadences let you cap catch-all volume and keep the main cadence clean. LeadOcean gives no refund for bounces, so read email_status before you send.
Which statuses should I send?
Send verified to the main cadence and catch_all_valid plus catch_all to the second. Leave risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, derived and none out.
What happens if the person already exists?
Salesloft treats the email address as a unique lookup on the team. The script prints any response that is not 200 and skips that row. Test with one known address first and read what comes back.
Can an AI agent run this?
The LeadOcean half can. LeadOcean's MCP server is at https://api.leadocean.io/mcp with 13 tools, including export_leads at one record per row. The Salesloft half of this recipe uses its REST API, so keep the script for the push.
Export your first Salesloft list with a free LeadOcean key
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →