Agent Skills
Discover and share powerful Agent Skills for AI assistants
apollo-core-workflow-a - Agent Skill - Agent Skills
Home/ Skills / apollo-core-workflow-a apollo-core-workflow-a MIT
Implement Apollo.io lead search and enrichment workflow.
Use when building lead generation features, searching for contacts,
or enriching prospect data from Apollo.
Trigger with phrases like "apollo lead search", "search apollo contacts",
"find leads in apollo", "apollo people search", "enrich contacts apollo".
Use the skills CLI to install this skill with one command. Auto-detects all installed AI assistants.
Method 1 - skills CLI
npx skills i jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/apollo-pack/skills/apollo-core-workflow-a CopyMethod 2 - openskills (supports sync & update)
npx openskills install jeremylongshore/claude-code-plugins-plus-skills CopyAuto-detects Claude Code, Cursor, Codex CLI, Gemini CLI, and more. One install, works everywhere.
Installation Path
Download and extract to one of the following locations:
Claude Code Cursor OpenCode Gemini CLI Codex CLI
~/.claude/skills/apollo-core-workflow-a/ Back No setup needed. Let our cloud agents run this skill for you.
Select Model
Claude Haiku 4.5 $0.10 Claude Sonnet 4.5 $0.20 Claude Opus 4.5 $0.50 Claude Sonnet 4.5 $0.20 /task
Best for coding tasks
Try NowNo setup required
Apollo Core Workflow A: Lead Search & Enrichment
Overview
Implement the primary Apollo.io workflow for searching leads and enriching contact/company data. This is the core use case for B2B sales intelligence.
Prerequisites
Completed apollo-sdk-patterns setup
Valid Apollo API credentials
Understanding of your target market criteria
Workflow Components
1. People Search
Search for contacts based on various criteria like company, title, location, and industry.
// src/services/apollo/people-search.ts
import { apollo } from '../../lib/apollo/client' ;
interface PeopleSearchCriteria {
domains ?: string [];
titles ?: string [];
locations ?: string [];
industries ?: string [];
employeeRanges ?: string [];
page ?: number ;
perPage ?: number ;
}
2. Company Enrichment
Enrich company data to get comprehensive firmographic information.
// src/services/apollo/company-enrichment.ts
import { apollo } from '../../lib/apollo/client' ;
export async function enrichCompany ( domain : string ) {
const response = await apollo. enrichOrganization (domain);
const org =
Enrich individual contacts with email and additional data.
// src/services/apollo/contact-enrichment.ts
export async function enrichContact ( params : {
email ?: string ;
firstName ?: string ;
lastName ?: string ;
domain ?: string ;
linkedinUrl
4. Complete Lead Generation Pipeline
// src/services/apollo/lead-pipeline.ts
import { searchPeople } from './people-search' ;
import { enrichCompany } from './company-enrichment' ;
import { enrichContact } from './contact-enrichment' ;
interface
Usage Example
// Example: Find engineering leads at fintech companies
const leads = await generateLeads ({
targetTitles: [ 'VP Engineering' , 'CTO' , 'Engineering Manager' ],
targetIndustries: [ 'financial services' , 'fintech' ],
minEmployees: 50 ,
maxEmployees: 500 ,
});
console. log ( `Found ${ leads
Output
Paginated people search results
Enriched company firmographic data
Enriched contact data with emails
Combined lead pipeline with scoring
Error Handling
Error Cause Solution Empty Results Too narrow criteria Broaden search parameters Missing Emails Contact not in database Try LinkedIn enrichment Rate Limited Too many enrichment calls Implement batching Invalid Domain Domain doesn't exist Validate domains first
Resources
Next Steps
Proceed to apollo-core-workflow-b for email sequences and outreach.
export
async
function
searchPeople
(
criteria
:
PeopleSearchCriteria
) {
const response = await apollo. searchPeople ({
q_organization_domains: criteria.domains,
person_titles: criteria.titles,
person_locations: criteria.locations,
q_organization_industry_tag_ids: criteria.industries,
organization_num_employees_ranges: criteria.employeeRanges,
page: criteria.page || 1 ,
per_page: criteria.perPage || 25 ,
});
return {
contacts: response.people. map (transformPerson),
pagination: response.pagination,
};
}
function transformPerson ( person : any ) {
return {
id: person.id,
name: person.name,
firstName: person.first_name,
lastName: person.last_name,
title: person.title,
email: person.email,
phone: person.phone_numbers?.[ 0 ]?.sanitized_number,
linkedin: person.linkedin_url,
company: {
id: person.organization?.id,
name: person.organization?.name,
domain: person.organization?.primary_domain,
},
};
}
response.organization;
return {
id: org.id,
name: org.name,
domain: org.primary_domain,
website: org.website_url,
industry: org.industry,
subIndustry: org.sub_industry,
employeeCount: org.estimated_num_employees,
annualRevenue: org.annual_revenue,
founded: org.founded_year,
description: org.short_description,
technologies: org.technologies || [],
locations: {
headquarters: {
city: org.city,
state: org.state,
country: org.country,
},
},
social: {
linkedin: org.linkedin_url,
twitter: org.twitter_url,
facebook: org.facebook_url,
},
};
}
?:
string
;
}) {
const response = await apollo. enrichPerson ({
email: params.email,
first_name: params.firstName,
last_name: params.lastName,
organization_domain: params.domain,
linkedin_url: params.linkedinUrl,
});
return {
... transformPerson (response.person),
enrichmentScore: calculateEnrichmentScore (response.person),
};
}
function calculateEnrichmentScore ( person : any ) : number {
let score = 0 ;
if (person.email) score += 30 ;
if (person.phone_numbers?. length ) score += 20 ;
if (person.linkedin_url) score += 15 ;
if (person.title) score += 10 ;
if (person.organization) score += 15 ;
if (person.city) score += 10 ;
return score;
}
LeadCriteria
{
targetDomains ?: string [];
targetTitles : string [];
targetLocations ?: string [];
targetIndustries ?: string [];
minEmployees ?: number ;
maxEmployees ?: number ;
}
export async function generateLeads ( criteria : LeadCriteria ) {
// Step 1: Search for matching contacts
const searchResults = await searchPeople ({
domains: criteria.targetDomains,
titles: criteria.targetTitles,
locations: criteria.targetLocations,
industries: criteria.targetIndustries,
});
// Step 2: Enrich companies for each unique domain
const uniqueDomains = [ ...new Set (
searchResults.contacts
. map ( c => c.company.domain)
. filter (Boolean)
)];
const enrichedCompanies = await Promise . all (
uniqueDomains. slice ( 0 , 10 ). map ( async ( domain ) => {
try {
return await enrichCompany (domain);
} catch {
return null ;
}
})
);
const companyMap = new Map (
enrichedCompanies
. filter (Boolean)
. map ( c => [c ! .domain, c])
);
// Step 3: Combine and filter results
return searchResults.contacts. map ( contact => ({
... contact,
company: companyMap. get (contact.company.domain) || contact.company,
}));
}
.
length
} leads`
);
leads. forEach ( lead => {
console. log ( `${ lead . name } - ${ lead . title } at ${ lead . company . name }` );
});