The credit estimates in the workflows below are illustrative — see Credits for your plan's exact rates.
Goal: Search for 200 VP of Sales at B2B SaaS companies similar to your best customer, then reveal their verified email addresses.
Endpoints used: Search People → Reveal Emails
Credit cost:
curl -X POST "https://api.ocean.io/v3/search/people" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": 200,
"peopleFilters": {
"seniorities": ["VP", "C-Level"],
"departments": ["Sales"],
"jobTitleKeywords": { "anyOf": ["Sales", "Revenue", "Commercial"] }
},
"companiesFilters": {
"lookalikeDomains": ["your-best-customer.com"],
"companySizes": ["51-200", "201-500"],
"industries": { "industries": ["B2B", "SaaS"] }
}
}'import requests
response = requests.post(
'https://api.ocean.io/v3/search/people',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'size': 200,
'peopleFilters': {
'seniorities': ['VP', 'C-Level'],
'departments': ['Sales'],
'jobTitleKeywords': {'anyOf': ['Sales', 'Revenue', 'Commercial']},
},
'companiesFilters': {
'lookalikeDomains': ['your-best-customer.com'],
'companySizes': ['51-200', '201-500'],
'industries': {'industries': ['B2B', 'SaaS']},
},
},
).json()
person_ids = [p['id'] for p in response['people']]const response = await fetch('https://api.ocean.io/v3/search/people', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
size: 200,
peopleFilters: {
seniorities: ['VP', 'C-Level'],
departments: ['Sales'],
jobTitleKeywords: { anyOf: ['Sales', 'Revenue', 'Commercial'] },
},
companiesFilters: {
lookalikeDomains: ['your-best-customer.com'],
companySizes: ['51-200', '201-500'],
industries: { industries: ['B2B', 'SaaS'] },
},
}),
}).then(r => r.json());
const personIds = response.people.map(p => p.id);The response includes an id field on each person. Collect these IDs.
Pass the IDs to Reveal Emails. Results arrive asynchronously to your webhookUrl.
curl -X POST "https://api.ocean.io/v2/reveal/emails" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"personIds": ["abc123", "def456", "...up to 500 IDs"],
"webhookUrl": "https://yourapp.com/webhooks/ocean-emails"
}'response = requests.post(
'https://api.ocean.io/v2/reveal/emails',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'personIds': person_ids, # from Step 1
'webhookUrl': 'https://yourapp.com/webhooks/ocean-emails',
},
).json()
# {"status": "in progress"} — results arrive at your webhookconst response = await fetch('https://api.ocean.io/v2/reveal/emails', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
personIds, // from Step 1
webhookUrl: 'https://yourapp.com/webhooks/ocean-emails',
}),
}).then(r => r.json());
// {"status": "in progress"} — results arrive at your webhookfrom flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/webhooks/ocean-emails", methods=["POST"])
def receive_emails():
data = request.json
for result in data["results"]:
person_id = result["personId"]
email = result["email"]["address"]
status = result["email"]["status"]
if status in ("verified", "guessed") and email:
# Add to your outreach sequence
add_to_crm(person_id, email)
return jsonify({"status": "ok"}), 200// Express.js
app.post('/webhooks/ocean-emails', (req, res) => {
for (const result of req.body.results) {
const { personId, email } = result;
if (['verified', 'guessed'].includes(email.status) && email.address) {
addToCrm(personId, email.address);
}
}
res.json({ status: 'ok' });
});Note
For cold outreach, prefer
verifiedemails.guessedemails are high-confidence but not SMTP-confirmed. AvoidcatchAlladdresses in high-volume campaigns.
Reference: Search People · Reveal Emails · Webhooks
Goal: You have 5 customers in a specific vertical. Find 500 similar companies to use as your next outreach segment.
Endpoints used: Search Companies (with lookalikeDomains)
Credit cost: 500 results × 0.2 credits = 100 credits
curl -X POST "https://api.ocean.io/v3/search/companies" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": 500,
"companiesFilters": {
"lookalikeDomains": [
"customer1.com",
"customer2.com",
"customer3.com"
],
"companySizes": ["51-200", "201-500"],
"primaryLocations": {
"includeCountries": ["us", "gb", "de"]
},
"excludeDomains": ["customer1.com", "customer2.com", "customer3.com"]
}
}'import requests
response = requests.post(
'https://api.ocean.io/v3/search/companies',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'size': 500,
'companiesFilters': {
'lookalikeDomains': ['customer1.com', 'customer2.com', 'customer3.com'],
'companySizes': ['51-200', '201-500'],
'primaryLocations': {'includeCountries': ['us', 'gb', 'de']},
'excludeDomains': ['customer1.com', 'customer2.com', 'customer3.com'],
},
},
).json()const response = await fetch('https://api.ocean.io/v3/search/companies', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
size: 500,
companiesFilters: {
lookalikeDomains: ['customer1.com', 'customer2.com', 'customer3.com'],
companySizes: ['51-200', '201-500'],
primaryLocations: { includeCountries: ['us', 'gb', 'de'] },
excludeDomains: ['customer1.com', 'customer2.com', 'customer3.com'],
},
}),
}).then(r => r.json());Tip: Diverse seeds cast a wider net
Using multiple different companies as
lookalikeDomainsbroadens the results. Using similar companies narrows them. Start with 3–5 of your best-fit customers.
import requests
def fetch_lookalike_companies(seed_domains, api_token, target_count=500):
url = "https://api.ocean.io/v3/search/companies"
headers = {"X-Api-Token": api_token, "Content-Type": "application/json"}
companies = []
search_after = None
while len(companies) < target_count:
payload = {
"size": min(100, target_count - len(companies)),
"companiesFilters": {
"lookalikeDomains": seed_domains,
"companySizes": ["51-200", "201-500"],
"excludeDomains": seed_domains
}
}
if search_after:
payload["searchAfter"] = search_after
response = requests.post(url, headers=headers, json=payload).json()
companies.extend(response["companies"])
search_after = response.get("searchAfter")
if not search_after:
break
return companiesasync function fetchLookalikeCompanies(seedDomains, apiToken, targetCount = 500) {
const url = 'https://api.ocean.io/v3/search/companies';
const headers = { 'X-Api-Token': apiToken, 'Content-Type': 'application/json' };
const companies = [];
let searchAfter;
while (companies.length < targetCount) {
const body = {
size: Math.min(100, targetCount - companies.length),
companiesFilters: {
lookalikeDomains: seedDomains,
companySizes: ['51-200', '201-500'],
excludeDomains: seedDomains,
},
};
if (searchAfter) body.searchAfter = searchAfter;
const data = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(body),
}).then(r => r.json());
companies.push(...data.companies);
searchAfter = data.searchAfter;
if (!searchAfter) break;
}
return companies;
}Each company object includes domain, name, companySize, industries, technologies, revenue, and more — enough to qualify accounts before reaching out.
Reference: Search Companies · Pagination
Goal: You have 1,000 company domains in your CRM with incomplete firmographic data. Enrich them all with company size, industry, technology stack, and revenue.
Endpoints used: Warmup Companies → Enrich Companies (Batch)
Credit cost: 1,000 enriched companies × 0.1 credits = 100 credits
Before enriching, check which domains are already in Ocean.io's database. Triggered domains need 2–5 minutes to index.
curl -X POST "https://api.ocean.io/v2/warmup/companies" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domains": ["company1.com", "company2.com", "...up to 500 domains"]
}'import requests
response = requests.post(
'https://api.ocean.io/v2/warmup/companies',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={'domains': ['company1.com', 'company2.com']},
).json()
# response["successfulDomains"] — ready now
# response["triggeredDomains"] — wait 2–5 minconst response = await fetch('https://api.ocean.io/v2/warmup/companies', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ domains: ['company1.com', 'company2.com'] }),
}).then(r => r.json());
// response.successfulDomains — ready now
// response.triggeredDomains — wait 2–5 minThe response splits domains into successfulDomains (ready now) and triggeredDomains (wait 2–5 min).
The Enrich Companies (Batch) endpoint takes up to 10,000 domains at once. Results are delivered to your webhook.
curl -X POST "https://api.ocean.io/v2/enrich/companies" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyDataMapping": {
"crm-account-001": { "company": { "domain": "company1.com" } },
"crm-account-002": { "company": { "domain": "company2.com" } }
},
"webhookUrl": "https://yourapp.com/webhooks/ocean-enrich"
}'response = requests.post(
'https://api.ocean.io/v2/enrich/companies',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'companyDataMapping': {
'crm-account-001': {'company': {'domain': 'company1.com'}},
'crm-account-002': {'company': {'domain': 'company2.com'}},
},
'webhookUrl': 'https://yourapp.com/webhooks/ocean-enrich',
},
).json()
# {"status": "in progress"} — results arrive at your webhookconst response = await fetch('https://api.ocean.io/v2/enrich/companies', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
companyDataMapping: {
'crm-account-001': { company: { domain: 'company1.com' } },
'crm-account-002': { company: { domain: 'company2.com' } },
},
webhookUrl: 'https://yourapp.com/webhooks/ocean-enrich',
}),
}).then(r => r.json());
// {"status": "in progress"} — results arrive at your webhookThe keys in companyDataMapping are your CRM IDs — they come back in the webhook payload so you can match enriched data to the right record.
@app.route("/webhooks/ocean-enrich", methods=["POST"])
def receive_enrichment():
data = request.json
for crm_id, result in data["results"].items():
if result["status"] == "found":
company = result["company"]
update_crm_account(crm_id, {
"industry": company.get("industries", []),
"employee_count": company.get("employeeCountOcean"),
"revenue": company.get("revenue"),
"technologies": company.get("technologies", [])
})
elif result["status"] == "triggered":
# Re-enrich this one in 5 minutes
schedule_retry(crm_id, delay_minutes=5)
return jsonify({"status": "ok"}), 200// Express.js
app.post('/webhooks/ocean-enrich', (req, res) => {
for (const [crmId, result] of Object.entries(req.body.results)) {
if (result.status === 'found') {
updateCrmAccount(crmId, {
industry: result.company.industries ?? [],
employeeCount: result.company.employeeCountOcean,
revenue: result.company.revenue,
technologies: result.company.technologies ?? [],
});
} else if (result.status === 'triggered') {
scheduleRetry(crmId, { delayMinutes: 5 });
}
}
res.json({ status: 'ok' });
});Reference: Enrich Companies (Batch) · Warmup Companies · Webhooks
Goal: You have 50 target account domains. Find all VP+ in Sales and Marketing at those companies, one contact per company.
Endpoints used: Search People (with includeDomains + peoplePerCompany)
Credit cost: Up to 50 results × 0.2 credits = ≤10 credits
curl -X POST "https://api.ocean.io/v3/search/people" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": 50,
"peoplePerCompany": 1,
"peopleFilters": {
"seniorities": ["VP", "C-Level", "Head", "Director"],
"departments": ["Sales", "Marketing and Advertising"]
},
"companiesFilters": {
"includeDomains": [
"targetaccount1.com",
"targetaccount2.com",
"targetaccount3.com"
]
}
}'import requests
response = requests.post(
'https://api.ocean.io/v3/search/people',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'size': 50,
'peoplePerCompany': 1,
'peopleFilters': {
'seniorities': ['VP', 'C-Level', 'Head', 'Director'],
'departments': ['Sales', 'Marketing and Advertising'],
},
'companiesFilters': {
'includeDomains': [
'targetaccount1.com',
'targetaccount2.com',
'targetaccount3.com',
],
},
},
).json()const response = await fetch('https://api.ocean.io/v3/search/people', {
method: 'POST',
headers: { 'X-Api-Token': 'YOUR_API_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
size: 50,
peoplePerCompany: 1,
peopleFilters: {
seniorities: ['VP', 'C-Level', 'Head', 'Director'],
departments: ['Sales', 'Marketing and Advertising'],
},
companiesFilters: {
includeDomains: ['targetaccount1.com', 'targetaccount2.com', 'targetaccount3.com'],
},
}),
}).then(r => r.json());peoplePerCompany: 1 ensures you get at most one contact per company, choosing the highest-matched person. Combine with seniorities to get the most senior person in your target department.
Want emails too?
Collect the returned
idvalues and pass them to Reveal Emails. With 50 contacts and a ~79% find rate, expect around 40 verified emails for roughly 40 credits.
Reference: Search People · Reveal Emails