You get a three-part pipeline: a LeadOcean export, split by email_status, loaded into two Instantly campaigns. Verified addresses go to your main campaign. Catch-all addresses go to a second campaign, so a bad domain cannot drag down the first. Both sides are plain REST with a key, so a short script does the job.
Use two exports, not one, because the status decides the risk. A verified address has been checked against the mailbox. A catch-all domain accepts everything, so a catch-all address may still bounce, and LeadOcean marks it as such in email_status. That is the whole reason to split.
Related: the LeadOcean integrations hub, the Smartlead recipe, the Reply.io recipe, the Salesloft recipe and pricing.
How it works
Six steps. Instantly takes up to 1,000 leads per request and checks them against your blocklist and existing leads (source: Instantly API reference, September 2026).
- Get both keys. Sign up at app.leadocean.io and copy a key from the API keys page. Create an Instantly API key with a scope that allows
leads:create. - Size the list. Run a free count before you spend records. A search with
count=trueandlimit=1costs nothing, andmeta.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 campaigns in Instantly. One for verified, one for catch-all. Copy both campaign ids.
- Push each CSV. Send 1,000 rows at a time to
POST /api/v2/leads/addwith the matchingcampaign_id.
Run a small test first. Free has no bulk CSV export, so on Free search with POST /v1/people/search, then call POST /v1/people/enrich with reveal_email set to true for each person to get the address. Each person returned costs one record. Check one lead in Instantly 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":"instantly 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, change emailStatus to ["catch_all_valid","catch_all"] and download to catchall.csv. Contact columns need a key with the enrich scope.
Step 6, the push. Instantly uses a bearer token and an api.instantly.ai base URL. The batch size of 1,000 is Instantly's documented maximum.
import csv, os, sys, time, requests
URL = "https://api.instantly.ai/api/v2/leads/add"
HEAD = {"Authorization": f"Bearer {os.environ['INSTANTLY_API_KEY']}"}
path, campaign_id = sys.argv[1], sys.argv[2]
leads = [{
"email": r["email_1_address"],
"first_name": r["profile_first_name"],
"last_name": r["profile_last_name"],
"company_name": r["current_company_name"],
"job_title": r["current_job_title"],
"website": r["current_company_domain"],
"custom_variables": {"email_status": r["email_1_status"]},
} for r in csv.DictReader(open(path)) if r["email_1_address"]]
for i in range(0, len(leads), 1000):
body = {"campaign_id": campaign_id, "leads": leads[i:i+1000],
"skip_if_in_workspace": True}
print(requests.post(URL, headers=HEAD, json=body).json())
time.sleep(2)Instantly's rate limit is shared by the whole workspace and by API v1 and v2 (source: Instantly rate limits, September 2026). A 10,000-row file is 10 requests, so the limit is not a problem here. It matters if other automations hit the same workspace.
Run it twice: python push.py verified.csv VERIFIED_CAMPAIGN_ID and python push.py catchall.csv CATCHALL_CAMPAIGN_ID. The response reports leads_uploaded, in_blocklist, duplicated_leads and invalid_email_count.
Field mapping
Map the status as well as the address. Instantly does not know which of your leads came from a catch-all domain, so write email_status into custom_variables and you can report on it later. It also lets you pull a bounced segment and trace it back to its status.
Instantly's bulk endpoint takes email, first_name, last_name, company_name, job_title, phone, website, personalization and custom_variables, plus a few status fields. The lead schema allows no other fields, so extra data goes in custom_variables (source: Instantly OpenAPI spec, September 2026).
| LeadOcean field | Instantly field | Note |
|---|---|---|
email_1_address | email | Required for a campaign. |
email_1_status | custom_variables.email_status | Lets you filter and report by status later. |
profile_first_name | first_name | Empty if the profile has no split name. |
profile_last_name | last_name | |
current_company_name | company_name | |
current_job_title | job_title | |
current_company_domain | website | Domain only. Add https:// if your templates link to it. |
phone_1_number | phone | Add the column to the export. Needs a plan with phones. |
Column ids come from GET /v1/exports/columns, which needs no key.
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. Instantly's Hypergrowth plan lists 25,000 uploaded contacts at $97 a month, and Growth stops at 1,000. All Instantly plans include API access; webhooks start at Hypergrowth (source: Instantly pricing, October 2026). Prices below are monthly billing.
| 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. |
| Instantly Growth | $47 a month | 1,000 uploaded contacts. Too small. |
| Instantly Hypergrowth | $97 a month | 25,000 uploaded contacts, 125,000 emails a month. |
| Instantly Light Speed | $358 a month | 100,000 uploaded contacts, 500,000 emails a month. |
Instantly bills by uploaded contacts and monthly emails, so a 10,000-lead list in one workspace sits well inside Hypergrowth. Count the emails too: a three-step sequence to 10,000 people is 30,000 sends. That sum is ours.
A first month of both tools is $194 at list price. That sum is ours.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 401 from Instantly | Missing or wrong bearer token. | Send Authorization: Bearer KEY, not x-api-key. |
| 400 from Instantly | A lead object has a field outside the schema. | Move extra columns into custom_variables. |
leads_uploaded below total_sent | Blocklist hits, duplicates or bad emails. | Read in_blocklist, duplicated_leads and invalid_email_count. |
| 429 from Instantly | Over 100 requests a second or 6,000 a minute for the workspace. | Keep the 2-second pause between batches. |
| 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. |
| 410 on LeadOcean download | The file expired. | Create the export again. |
FAQ
Why split catch-all from verified?
A catch-all domain accepts any address, so you cannot confirm the mailbox exists. Verified addresses carry less bounce risk. Separate campaigns let you cap catch-all volume and keep the main campaign clean. LeadOcean gives no refund for bounces, so read email_status before you send.
Which statuses should I send?
Send verified to the main campaign and catch_all_valid plus catch_all to the second. Leave risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, derived and none out.
Can an AI agent run this?
Yes. LeadOcean's MCP server is at https://api.leadocean.io/mcp with 13 tools, including export_leads at one record per row. Instantly runs its own MCP server that exposes its V2 API, bulk lead add included (source: Instantly MCP docs, October 2026).
Export your first Instantly 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 →