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

How-to guide

How to Build a LeadOcean, Smartlead and Pipedrive Outbound Stack (List, Verify, Send)

Export a filtered list from LeadOcean, load it into Smartlead through the API, and create a Pipedrive person when someone replies. Sizing is free; the CSV export needs Solo.

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

This stack gives each tool one job. LeadOcean builds the list, Smartlead sends the sequence, and Pipedrive holds the people who reply. The free plan sizes the list. The CSV export in step 2 needs Solo.

The example audience is US sales directors with a verified work email. Swap the filters for yours.

TL;DR

  • Time: about 90 minutes for a 200-row pilot, plus the mailbox warmup you already run in Smartlead.
  • Records: 200 to 400 LeadOcean records for the pilot. Sizing is free. The free plan has 1,000 records, one-off, but bulk CSV export is not on Free, so the pilot export needs Solo.
  • Cost per 10,000 contacts: $97 for LeadOcean Solo plus $94 for Smartlead Pro, $191 a month at monthly list prices, or $175 with Smartlead billed yearly. Mailboxes and Pipedrive seats are on top. Step 6 shows the arithmetic.

Prerequisites

  • A LeadOcean key in $LEADOCEAN_API_KEY. Sign up at app.leadocean.io/register. No card needed. Free covers step 1; the step 2 export needs Solo ($97 a month) or Agency ($497 a month).
  • A Smartlead plan with API access and at least one connected, warmed mailbox. Smartlead says API access depends on your plan (Smartlead docs, October 2026). Your key is in $SMARTLEAD_API_KEY.
  • A Pipedrive account with an API token in $PIPEDRIVE_API_TOKEN and your company domain in $PIPEDRIVE_DOMAIN.
  • curl and Python 3 with the requests package.

Step 1: Size the list before you spend anything

Count first. A search with count=true and limit=1 costs nothing (LeadOcean API reference, September 2026).

bash
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"],"emailType":["work"],"emailStatus":["verified"],"limit":1}'

Read meta.total. It is capped at 100,000. Filters join with AND, and several values inside one filter join with OR.

Step 2: Export the pilot list

Export 200 rows, not the whole audience. Bulk CSV export is included on Solo and Agency, not on Free. The export is asynchronous and reserves records up front (LeadOcean docs, September 2026).

bash
curl -X POST https://api.leadocean.io/v1/exports \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"us-sales-directors pilot","filters":{"jobLevel":["Director"],"jobFunction":["Sales & Business Development"],"country":["US"],"emailType":["work"],"emailStatus":["verified"]},"limit":200,"columns":["person_id","profile_first_name","profile_last_name","profile_url","current_job_title","current_company_name","current_company_domain","email_status","email_N_address"],"caps":{"emails":1}}'

The answer is a 202 with an export id. Poll GET /v1/exports/{id} until status is done, then download.

bash
curl -H "x-api-key: $LEADOCEAN_API_KEY" -o leads.csv \
  https://api.leadocean.io/v1/exports/EXPORT_ID/download

One export takes up to 50,000 rows, and an account takes 500,000 rows a day.

Step 3: Decide what counts as sendable

LeadOcean tags every address with email_status. The export above asks for verified only, so the file needs no second pass. If you widen it to catch_all_valid or catch_all, you accept more bounce risk. There is no refund for bounced emails, so read the status before you send.

The Smartlead pricing page also lists a "Verified Emails" allowance on each plan (Smartlead pricing, October 2026). Use it on the catch_all rows if you include them. Keep verified rows out of it so the allowance goes further.

text
Send now:        email_status == verified
Send after check: email_status == catch_all_valid or catch_all  (run Smartlead verification first)
Never send:      risky, unknown, untested, invalid, role, disposable, spam_trap, abuse, none

Step 4: Load the leads into Smartlead

Before the load, set the campaign up so the first send is safe. Keep the pilot small, use two or three mailboxes that finished warmup, and write a three-step sequence with plain-text copy. Personalise with the columns you exported: first name, company and job title. Do not send a sequence you have not read as a recipient.

Create the campaign and its sequence in the Smartlead app, and copy the campaign id from the URL. Then push the CSV through the API. Smartlead accepts up to 400 leads per request and checks them against block lists and duplicates (Smartlead API, October 2026).

python
import csv, os, requests

CAMPAIGN_ID = 123456  # from the Smartlead campaign URL
URL = f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/leads"
KEY = os.environ["SMARTLEAD_API_KEY"]

rows = [r for r in csv.DictReader(open("leads.csv")) if r["email_status"] == "verified"]

def lead(r):
    return {
        "email": r["email_1_address"],
        "first_name": r["profile_first_name"],
        "last_name": r["profile_last_name"],
        "company_name": r["current_company_name"],
        "website": r["current_company_domain"],
        "linkedin_profile": r["profile_url"],
        "custom_fields": {"job_title": r["current_job_title"],
                          "leadocean_person_id": r["person_id"]},
    }

for i in range(0, len(rows), 400):
    batch = [lead(r) for r in rows[i:i + 400]]
    resp = requests.post(URL, params={"api_key": KEY}, json={"lead_list": batch,
        "settings": {"ignore_global_block_list": False,
                     "ignore_unsubscribe_list": False}})
    print(resp.status_code, resp.json())

Smartlead authenticates with an api_key query parameter and has no OAuth or bearer token (Smartlead docs, October 2026). Keep the key out of logs and shared shells.

Run the pilot first. Load 200 leads, send for a few days, and read bounces and replies before you export the next batch. The bounce rate on verified rows tells you whether the filter is right for your audience.

The response reports added_count and skipped_count. Skipped rows are duplicates or block-listed addresses.

Step 5: Create a Pipedrive person when someone replies

Smartlead webhooks push events such as a reply received, a bounce or an unsubscribe to any HTTP endpoint (Smartlead docs, October 2026). Create a webhook for the reply event in Smartlead, point it at a small receiver, and have the receiver call Pipedrive.

Pipedrive's Persons API takes a required name plus an emails array, each with a value and a primary flag (Pipedrive docs, October 2026). The token goes in the x-api-token header, and calls go to your company domain at https://companydomain.pipedrive.com (Pipedrive docs, October 2026). Smartlead's EMAIL_REPLY event carries the lead's address in to_email and name in to_name (Smartlead docs, October 2026).

python
import os, requests
from flask import Flask, request

app = Flask(__name__)
PD = f"https://{os.environ['PIPEDRIVE_DOMAIN']}.pipedrive.com/api/v2/persons"
HEADERS = {"x-api-token": os.environ["PIPEDRIVE_API_TOKEN"]}

@app.post("/smartlead/reply")
def reply():
    event = request.get_json()
    if event.get("event_type") != "EMAIL_REPLY":
        return {"skipped": True}, 200
    email = event["to_email"]               # the lead who replied
    name = event.get("to_name") or email
    body = {"name": name, "emails": [{"value": email, "primary": True}]}
    r = requests.post(PD, headers=HEADERS, json=body)
    return {"pipedrive_status": r.status_code}, 200

Pipedrive's person create call costs 5 API tokens in its v2 docs (Pipedrive docs, October 2026). Only repliers become Persons, so a 10,000-contact send creates a few hundred calls, not 10,000. Check for an existing Person with the same email before you create one.

Reply handling is a rule, not a feature of the list. Decide up front who owns a Person once it lands in Pipedrive, and what moves a Person into a deal. Write that down before volume goes up. Otherwise replies sit in two inboxes and nobody follows up.

Step 6: Cost a 10,000-contact run and know where each tool stops

Price the run before you scale. This is arithmetic from list prices, not a quote.

python
contacts = 10_000
steps = 3                       # emails per sequence
sends = contacts * steps        # 30,000 sends

leadocean_solo = 97             # flat per month, fair-use pace, no per-record price
smartlead_pro = (94, 78)        # monthly list, billed yearly per month
smartlead_pro_sends = 90_000    # Pro plan allowance per month
smartlead_pro_contacts = 30_000 # Pro contact storage

assert sends <= smartlead_pro_sends and contacts <= smartlead_pro_contacts
print("Sends:", sends, "of", smartlead_pro_sends)
print("Monthly list:", leadocean_solo + smartlead_pro[0])
print("Smartlead billed yearly:", leadocean_solo + smartlead_pro[1])
print("Per contact:", round((leadocean_solo + smartlead_pro[0]) / contacts, 4))

It prints 30,000 sends of a 90,000 allowance, $191 a month at monthly list prices, $175 with Smartlead billed yearly, and about $0.0191 a contact. Smartlead's pricing page lists Pro at $94 a month, or $78 a month billed yearly, with 30,000 contacts, 90,000 email sends and 30,000 verified emails (Smartlead pricing, October 2026). Mailboxes are extra: the same page lists SmartSenders from $13 a domain a year and $4.5 a mailbox a month.

LeadOcean Solo is $97 a month flat, with a fair-use pace instead of credits, and 10,000 contacts use 10,000 to 20,000 records. Agency is $497 a month if a team shares the keys. See pricing. Pipedrive seats are on top. Its pricing page blocked our check, so read the seat price for your plan at pipedrive.com/en/pricing.

Where each tool stops:

  • LeadOcean stops at the list. It has no sequencer, dialer, CRM or Chrome extension. email_status is a signal, and bounces are not refunded.
  • Smartlead stops at sending. It does not supply your contact data, and your deliverability depends on your domains and mailboxes.
  • Pipedrive stops at the deal record. It does not send your cold sequence in this stack, and it only sees people who replied.

What you get

Step 1 is a free count. We ran the same audience through LeadOcean's MCP leadocean_count_leads tool on 2026-10-21, with these filters: job level Director, function Sales & Business Development, country US, work email, status verified.

text
total 65150   totalIsExact true   distinctCompanies 28353   credits 0

That is a count of verified work emails, not of everyone matching the other filters. Your numbers will differ.

The export create call answers with the shape below. This is the response shape from the API reference (openapi.json), with placeholder values.

json
{
  "success": true,
  "data": {
    "id": "EXPORT_ID",
    "name": "us-sales-directors pilot",
    "status": "queued",
    "requested": 200,
    "estimatedTotal": 65150,
    "perRow": 1,
    "remaining": null,
    "pollAfter": 5
  }
}

requested is the records reserved and perRow is 1 or 2. remaining is null on a paid plan, which has a pace rather than a balance. Read perRow before you scale up. The Smartlead load answers with added_count and skipped_count, shown in its API reference.

Troubleshooting

ErrorCauseFix
401 "Missing or malformed x-api-key"The LeadOcean header is missing or wrong.Send x-api-key: $LEADOCEAN_API_KEY.
402 on export createFewer records are left than the export reserves.Lower limit. On Free the 1,000 records are one-off, and bulk CSV export is not on Free.
429 from LeadOceanMore requests a second than your plan allows (5 on Free, 50 on Solo, 200 on Agency), or a daily export ceiling.Honour Retry-After. Exports allow 500,000 rows a day.
Zero rows backA filter value is outside the catalogue, such as United States for US.Read the valid values from GET /v1/enums.
422 from SmartleadA lead failed validation, such as a bad email format or a missing required field.Check the rows in the failing batch (Smartlead API, October 2026).
429 from SmartleadThe docs cite 10 requests per 2 seconds.Back off and retry with a pause between batches (Smartlead docs, October 2026).

FAQ

Do I need Pipedrive at all?

Not to send. Smartlead has its own inbox for replies. Pipedrive earns its place when replies turn into deals that a rep owns and forecasts.

How many records does a full run cost?

One export row costs one record, or two when the create response shows perRow of 2. Solo at $97 a month and Agency at $497 a month have no per-record price, only a fair-use pace. See pricing.

Should I send to catch-all addresses?

Only after a second check, and only a small slice first. The VerifyHQ and ReachHQ stack shows a dedicated verify-then-send route.

Can I use a different CRM or sender?

Yes. The n8n and Attio stack wires the same list step to another CRM, and the lemlist and HubSpot stack swaps the sender. Back to the blog hub.

Build your first LeadOcean list for Smartlead and Pipedrive. Start free.

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →