SKILL.md
LinkedIn Profile Search Scraper (Apify)
Search LinkedIn profiles and extract detailed information using the Apify harvestapi/linkedin-profile-search actor (ID: M2FMdjRVeF1HPGFcc). No cookies or LinkedIn account required.
How to Run
# Keyword search (e.g., find agency founders)
node skills/linkedin-profile-scraper/scripts/apify-linkedin-search.js \
--query "agency founder" --max 100
# Keyword + location filter
node skills/linkedin-profile-scraper/scripts/apify-linkedin-search.js \
--query "marketing manager" --location "Austin" --max 50
# Full profile mode (more details, $4/1k)
node skills/linkedin-profile-scraper/scripts/apify-linkedin-search.js \
--query "CEO" --mode full --max 50
# Full profile + email search ($10/1k)
node skills/linkedin-profile-scraper/scripts/apify-linkedin-search.js \
--query "founder" --mode email --max 25 --campaign "founder_outreach"
# Dry run (no DB writes)
node skills/linkedin-profile-scraper/scripts/apify-linkedin-search.js \
--query "developer" --dry-run
Arguments
| Option |
Description |
Default |
--query |
Search keywords (e.g., "agency founder") |
- |
--location |
Filter by location (city/country) |
- |
--max |
Max profiles to return |
100 |
--mode |
Scraping depth (search/full/email) |
search |
--campaign |
Campaign name for DB tracking |
linkedin_search |
--dry-run |
Preview leads without storing |
false |
Modes & Pricing
| Mode |
Description |
Cost |
search |
Search page results (basic info) |
$0.10 per page (25 profiles) |
full |
Full profile details |
$4 per 1,000 profiles |
email |
Full profile + email search |
$10 per 1,000 profiles |
Environment Variables
APIFY_API_KEY=xxx # Required - Apify API token
DATABASE_URL=xxx # Required - PostgreSQL connection string
Apify Actor
| Actor |
ID |
Features |
| LinkedIn Profile Search Scraper |
M2FMdjRVeF1HPGFcc |
No cookies, keyword search, email lookup |
| Developer |
HarvestAPI |
|
Output Per Profile
{
"publicIdentifier": "john-doe-123",
"linkedinUrl": "https://www.linkedin.com/in/john-doe-123",
"firstName": "John",
"lastName": "Doe",
"headline": "Founder & CEO at Acme Agency",
"location": {
"linkedinText": "San Francisco, CA",
"parsed": { "city": "San Francisco", "country": "United States" }
},
"connectionsCount": 500,
"premium": false,
"openToWork": true,
"currentPosition": [{ "companyName": "Acme Agency", "title": "Founder" }],
"email": "[email protected]" // Only in email mode
}
Database
Stores in linkedinleads table (deduped by publicidentifier):
| Column |
Description |
| public_identifier |
LinkedIn username (unique) |
| linkedin_url |
Full profile URL |
| firstname, lastname |
Name |
| headline |
Job headline |
| location, locationcity, locationcountry |
Location info |
| currentcompany, currenttitle |
Current job |
| connectionscount, followercount |
Network size |
| isopentowork, ishiring |
Status flags |
| email |
Found email (email mode only) |
| campaign_name |
Campaign identifier |
| contacted, connectionsent, dmsuccess |
Outreach tracking |
Notes
- LinkedIn limits search results to ~2,500 per query
- For larger datasets, split by location or use more specific keywords
- Email search performs SMTP validation; not guaranteed for every profile
- Auto-skips own accounts (loaded from onboarding-config.json)