LinkedIn Profile Email Finder — Pay Per Find
Pricing
from $4.00 / 1,000 usable linkedin profiles
LinkedIn Profile Email Finder — Pay Per Find
LinkedIn public profiles → one dataset row per URL, optional verified work email. Pay only for usable profiles and emails found. Privacy: https://api.apify.com/v2/key-value-stores/jZUn8TR3AeaEwtT2h/records/linkedin-profile-verified-email-privacy.en.html?signature=PcrXf7uRJ0kRmb0GyaoF
Pricing
from $4.00 / 1,000 usable linkedin profiles
Rating
5.0
(2)
Developer
Pequod
Maintained by CommunityActor stats
1
Bookmarked
330
Total users
89
Monthly active users
a day ago
Last modified
Categories
Features
Share
LinkedIn Profile + Verified Email — Pay Only When Found
Pay-per-event actor that delivers one dataset row per input URL, in input order, and bills only after the row is written to the dataset.
Provide public LinkedIn profile URLs. The actor looks up the public profile
through an upstream profile data provider (name, headline, current job title,
company, location and, by default, the full profile: experience, education,
skills and the other public sections) and, with findEmail on, finds the
company's domain and runs an email cascade that charges only when the work
email passes SMTP verification.
Features
- One row per URL — input order preserved; with
skipDuplicates(the default) a repeated URL gets its own row, marked withduplicateOfInputIndex, and is never charged twice - Public profile fields — full, first and last name, headline, current job title, company name and LinkedIn company page, location with city, country and country code, public identifier and canonical profile URL
- Full profile — about, photo, follower and connection counts, websites,
experience, education, skills, certifications, languages, projects,
publications, honors, courses and patents in fixed shapes (
profileDetail, below); sections that can reveal sensitive data or other people's data are never written to your dataset - Company domain — resolved separately (web search, then a company-page
lookup) when
findEmailis on; the profile data itself carries no company website - Verified work email — company domain → person-shaped patterns
(
{first}.{last},{f}.{last}, …) and, on paid Apify plans, business email records → SMTP verification;verifiedonly when MillionVerifier answersokwith good quality - Catch-all guesses returned, never billed —
emailConfidence=riskyon catch-all domains;email-foundfires only forverified - Transparent billing —
qualifiedEvents/excludedEventson every row; amounts in the key-value recordbilling-reconciliation - Billing is safe to resume — if the platform restarts or migrates a run, rows already charged are never charged again; the lookups of rows not yet delivered are repeated
- Progress you can read — the run's status line names the current step and ends with a summary: rows, usable profiles, verified emails, and rows not charged with the reason
Input
| Field | Type | Default | Description |
|---|---|---|---|
profileUrls | string[] | required | LinkedIn public profiles, one per entry (formats below). startUrls or urls lists are accepted too |
profileDetail | string | full | full: the core fields plus the full profile sections; core: the core fields only. Both are charged the same |
findEmail | boolean | true | Resolve the company domain and run the email cascade on usable profiles |
acceptPatternEmails | boolean | true | Legacy option kept so saved tasks keep working. Only SMTP-verified emails are ever charged; catch-all guesses are written as risky and never charged |
skipDuplicates | boolean | true | Charge a repeated URL only once; the repeat still gets its row |
maxConcurrency | integer | 8 | Profiles enriched in parallel (search lookups and email checks) |
maxRetriesPerProfile | integer | 1 | Fallback page scraper only (off by default): page attempts per profile |
enableBrowserFallback | boolean | false | Fallback page scraper only: anonymous browser attempt, never with LinkedIn login cookies |
proxyConfiguration | object | DATACENTER | Fallback page scraper only: Apify Proxy settings |
The last three settings apply only to the emergency fallback scraper, which is off by default; standard runs ignore them.
Accepted profile formats
The formats customers sent between 2026-10-10 and 2026-11-11, and what this release does with each (the expected behaviour of this release, tested on synthetic data):
| You send | Result |
|---|---|
https://www.linkedin.com/in/<public-id>/ on any LinkedIn subdomain, http or https, with or without a trailing slash or query string | matched |
linkedin.com/in/<public-id> without https:// | matched |
a bare public identifier such as jane-doe-test | matched |
https://www.linkedin.com/in/ACoA… profile-id URLs | matched (they came back not_found before this release) |
| a renamed or redirected public identifier | matched to the profile the provider returns |
company or school pages, Sales Navigator links, /pub/ links, other text | sent as they are; not_found unless the provider returns a profile for them, and not_found is never charged |
Repeats are detected on the URL text, ignoring case and a trailing slash. Two
different forms of the same profile (for example a vanity URL and its
ACoA… URL) are two rows, and each can be charged.
Apify free plan
On the Apify platform, free-plan users get the product with limits that keep upstream costs sustainable:
| Limit | Free plan | Paid Apify plan |
|---|---|---|
profileUrls entries per run | 25 (extra entries dropped, no rows) | No cap |
| Profiles per account and UTC calendar month | 100 | No cap |
| Email lookups per account and UTC calendar month | 20 | No cap |
| Business email records (B2B databases) | never used | used |
A profile counts against the monthly allowance when a run starts processing
its URL, whatever the result (a not_found URL counts too); URLs beyond the
remaining allowance get no rows, so once the allowance is used up a run
returns no rows. An email lookup counts when the email search starts for a
usable row whose company domain was found, whether or not an address is
found; once the 20 lookups are used up, rows get emailSkipReason
free_trial_exhausted. On the free plan emails come only from person-shaped
patterns checked by SMTP verification, so an address that only business
records know is not found. The allowances are counted per Apify account under
a pseudonymous key (see "Usage statistics" below). Upgrade at
Apify pricing for unlimited usage.
Full profile (profileDetail)
With profileDetail set to full (the default), every usable row also
carries the public profile sections the profile lookup returns, in fixed
shapes (no other key is ever copied through):
| Field | Content |
|---|---|
about | the About text, at most 2,600 characters |
photoUrl | profile photo URL (image links can expire) |
followerCount, connectionsCount | counts shown on the profile |
openToWork, hiring, premium | flags shown on the profile |
websites | website URLs listed on the profile |
experience | title, companyName, companyLinkedinUrl, companyId, location, employmentType, workplaceType, startDate, endDate, isCurrent, description |
education | schoolName, schoolLinkedinUrl, degree, fieldOfStudy, startDate, endDate |
skills, topSkills | skill names without repeats (no endorsements) |
certifications | name, authority, issuedAt, url |
languages | name, proficiency |
projects | title, description, startDate, endDate (no contributors) |
publications | title, publisher, date, url |
honorsAndAwards | title, issuer, date |
courses | name |
patents | title, number, date |
Each list keeps at most 50 entries; descriptions are cut at 2,000 characters
and other texts at 500; dates are YYYY-MM or YYYY; a current position has
endDate null and isCurrent true. A section the profile does not have is an
empty list, a section that could not be read is null. With core, and on
rows without a profile (not_found, error) or from the emergency fallback
scraper, all these fields are null. The free-text fields (about,
descriptions) hold whatever the person wrote on their public profile.
Never written to your dataset, by design (GDPR): interests, causes and volunteering, because they can reveal special categories of personal data such as religious or political beliefs, health or trade-union membership (art. 9 GDPR); received and given recommendations and the "more profiles" lists of similar people, because they are other people's data; and pronouns, memorial status, account creation date, profile actions, connected apps, section totals and featured items. Nested third-party data such as project contributors and skill endorsements is left out too. The profile provider returns these sections with the rest of the profile: the Actor discards them in memory and never writes them to your dataset or to the run's records. Like everything the provider returns, they pass through its sub-run on the developer's Apify account, and the Actor deletes that sub-run's input and results right after reading them (see "Usage statistics" below for what stays and when the deletion can fail).
Both settings are charged the same. Choose core when you do not need the
extra sections, so your dataset holds only the personal data you need (the
profile lookup itself does not change); it also keeps
CSV and Excel exports narrow, since exports flatten every list entry into its
own columns (for example experience/0/title). The Full profile view of
the dataset shows the sections side by side; open a cell or export as JSON to
read the lists.
Output
Each dataset row has these fields:
| Group | Fields |
|---|---|
| Input and outcome | inputUrl, inputIndex, status (ok | partial | not_found | blocked | error), duplicateOfInputIndex |
| Person | fullName, headline, location |
| Company | companyName, companyLinkedinUrl, companyLinkedinId, companyDomain, companyDomainSource, companyDomainConfidence, companyDomainSignals |
email, emailConfidence (verified | risky), emailSkipReason, emailEvidence | |
| Billing | qualifiedEvents, excludedEvents |
| Diagnostics | errorMessage, acquisitionSource, attempts, lastHttpStatus, scrapedAt |
| Profile details | firstName, lastName, jobTitle, publicIdentifier, profileUrl, city, country, countryCode |
| Full profile | about, photoUrl, followerCount, connectionsCount, openToWork, hiring, premium, websites, experience, education, skills, topSkills, certifications, languages, projects, publications, honorsAndAwards, courses, patents |
The profile details come after scrapedAt and the full-profile fields after
countryCode, so CSV exports keep the earlier column positions; they are
empty when the data source does not provide them.
status is ok with a name and a company, partial with a name only,
not_found when the profile does not exist or was not returned, and error
for an empty entry or a failed lookup (blocked only occurs on the fallback
scraper). emailSkipReason says why a usable row has no email: no_domain,
catch_all_domain_not_trusted, no_candidate_valid, free_trial_exhausted
or cascade_error; it is empty when findEmail is off.
The run's key-value record RUN_SUMMARY counts the run's statuses, usable
rows, emails found, verified emails, email skip reasons and not-found causes.
How the email is found
- The company's website domain is resolved: web search first, then a company-page lookup. Domain search uses hostname, result title and snippet, search rank, repeated results and LinkedIn company identity signals; low-score and near-tied matches are rejected instead of guessing.
- Candidate addresses come from person-shaped patterns (
{first}.{last},{f}.{last}, …; Dutch surname particles are kept when building the top five candidates) and, on paid Apify plans, from business email records. - Every candidate is checked by SMTP verification:
verifiedonly when MillionVerifier answersokwith good quality. On a catch-all domain the best guess is returned asriskyand never charged.
Two lookup orders are in use on paid plans while we measure which one finds more verified emails per dollar: business records first for every company, or the patterns first and business records only for the rows the patterns did not resolve (fewer records per company, no search by name alone). Each run gets one order at random, from the run ID the platform assigns; both are charged the same, and only verified emails are charged.
Pricing (pay per event)
You pay for results only:
| Event | Price (USD) | When it is charged |
|---|---|---|
email-found | 0.028 | Once per row whose work email passed SMTP verification (emailConfidence = verified) |
profile | 0.004 | Once per usable row: fullName + companyName, status not blocked / error / not_found, not a repeat |
apify-actor-start | 0.00005 | Automatically once per run at 1 GB (runs use 1,024 MB) |
A price change is always announced by Apify to this Actor's users at least 14 days before it takes effect, and listed here with its date.
Worked examples (add $0.00005 per run for the start event):
- 1,000 URLs, all usable,
findEmailon, 25% verified: 1,000 × $0.004 = $4 for profiles + 250 × $0.028 = $7 for emails = $11, or $0.044 per verified email. - Profile only (
findEmailoff): $4 per 1,000 usable profiles, the full profile included.
Never charged: rows with status not_found, error or blocked; usable
rows without a name or a company; repeated URLs (with skipDuplicates, the
default); catch-all guesses (emailConfidence = risky) and rows where no
address passed verification; the full profile itself (full and core cost
the same); rows delivered after the run's maximum charge was reached.
How to verify your invoice
Open the run's Key-value store → record billing-reconciliation:
{"byInputIndex": {"0": { "profile": 0.004, "email-found": 0.028 },"1": {}},"totalUsd": 0.032,"rowsDelivered": 2,"rowsCharged": 1}
The record holds the price your run was actually charged, as the platform reported it when the run started. Rows do not embed charged amounts (datasets are append-only). Use the KV record to match the Apify invoice.
Legal / GDPR
Public Art. 13–14 privacy notice (hosted on Apify KV, permanent signed URL): privacy notice.
Notice source and URL manifest: ./docs/privacy/README.md.
Usage statistics. To find out where runs spend their time, what they cost and whether customers come back, each run sends its developer one technical record of numbers, yes/no flags and fixed categories only: build, timeout, memory, the number of profile entries (and how many were empty, repeated or dropped by a free-plan limit), the kinds of input formats and which input field held them, your options (findEmail, acceptPatternEmails, skipDuplicates, profileDetail, the fallback and concurrency settings, the proxy type), which email lookup order the run was given, the run's stage or outcome, restarts and platform events (abort, migration), which steps were running or entered and how long they took, counts of the results by fixed categories (statuses, data sources, email outcomes and skip reasons, billable and charged events, rows with a full profile, the top-level domain of company websites such as .com or .de, and whether names are plain, accented or decorated), counts of the paid lookups the run made and of whether each lookup's data could be deleted, whether your Apify plan is free or paid, whether the free-plan limits applied and how much of the monthly allowances the run used or was refused and, once the developer has configured it, a pseudonymous account key. The key is a keyed hash of your Apify account ID made with a secret only the developer holds: it is the same on all your runs, so returning customers can be counted, and the record never contains the account ID itself. The free plan's monthly allowances are counted in a store of the developer under a second pseudonymous key, a keyed hash of your account ID made with the same secret (until the developer configures that secret, an unkeyed hash that anyone who knows the account ID can recompute), next to the month and the time of each reservation. Pseudonymous is not anonymous: with that secret, by matching run dates with the free plan's allowance keys, or by matching the timing of the lookups described below, the developer can tell which records and lookups belong to an account. The record is filed under a one-way hash of the run ID and the run date, and never contains your profile URLs, names, headlines, companies, domains, locations or emails. The profile URLs you submit, and what the data providers return for them (the whole profile, also the sections never written to your dataset, and the business email records' contacts of the same company, other people included, or, after a search by name alone, of people with a similar name at other companies), go through actors that run on the developer's Apify account. Each lookup's input and results are deleted right after the Actor reads them. What stays there is the lookup's run metadata (status, timing, cost and the Actor's user agent), kept for cost accounting, with the log and status message the provider's actor wrote during the run, which can mention what it looked up. The deletion can fail: during an Apify outage, when a lookup's start is interrupted before the Actor learns which run it started, or when your run is aborted, times out or is moved to another server by the platform while a lookup is running (that lookup then runs to its end); the developer can also switch it off to investigate a fault. Then that lookup's input and results stay on the developer's account, readable by the developer, until the platform's data retention removes them (the developer understands this to be 31 days for its account but has not yet confirmed it; Apify can keep the most recent runs longer).
Pequod ecommerce pipeline
| Step | Actor | When |
|---|---|---|
| 1. Discover restaurants | Restaurant Leads | Restaurant email list from Google Maps |
| 1. Discover local businesses | Google Maps Local Leads | Horizontal local leads |
| 2. Enrich contact | Decision Maker Finder | Named decision makers on a company domain |